420 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			420 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								/* boost random/uniform_int_distribution.hpp header file
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright Jens Maurer 2000-2001
							 | 
						||
| 
								 | 
							
								 * Copyright Steven Watanabe 2011
							 | 
						||
| 
								 | 
							
								 * Distributed under the Boost Software License, Version 1.0. (See
							 | 
						||
| 
								 | 
							
								 * accompanying file LICENSE_1_0.txt or copy at
							 | 
						||
| 
								 | 
							
								 * http://www.boost.org/LICENSE_1_0.txt)
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * See http://www.boost.org for most recent version including documentation.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * $Id$
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Revision history
							 | 
						||
| 
								 | 
							
								 *  2001-04-08  added min<max assertion (N. Becker)
							 | 
						||
| 
								 | 
							
								 *  2001-02-18  moved to individual header files
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef BOOST_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP
							 | 
						||
| 
								 | 
							
								#define BOOST_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <iosfwd>
							 | 
						||
| 
								 | 
							
								#include <ios>
							 | 
						||
| 
								 | 
							
								#include <istream>
							 | 
						||
| 
								 | 
							
								#include <boost/config.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/limits.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/assert.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/random/detail/config.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/random/detail/operators.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/random/detail/uniform_int_float.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/random/detail/signed_unsigned_tools.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/random/traits.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/mpl/bool.hpp>
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
							 | 
						||
| 
								 | 
							
								#include <boost/mpl/if.hpp>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost {
							 | 
						||
| 
								 | 
							
								namespace random {
							 | 
						||
| 
								 | 
							
								namespace detail {
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_MSVC
							 | 
						||
| 
								 | 
							
								#pragma warning(push)
							 | 
						||
| 
								 | 
							
								// disable division by zero warning, since we can't
							 | 
						||
| 
								 | 
							
								// actually divide by zero.
							 | 
						||
| 
								 | 
							
								#pragma warning(disable:4723)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class Engine, class T>
							 | 
						||
| 
								 | 
							
								T generate_uniform_int(
							 | 
						||
| 
								 | 
							
								    Engine& eng, T min_value, T max_value,
							 | 
						||
| 
								 | 
							
								    boost::mpl::true_ /** is_integral<Engine::result_type> */)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    typedef T result_type;
							 | 
						||
| 
								 | 
							
								    typedef typename boost::random::traits::make_unsigned_or_unbounded<T>::type range_type;
							 | 
						||
| 
								 | 
							
								    typedef typename Engine::result_type base_result;
							 | 
						||
| 
								 | 
							
								    // ranges are always unsigned or unbounded
							 | 
						||
| 
								 | 
							
								    typedef typename boost::random::traits::make_unsigned_or_unbounded<base_result>::type base_unsigned;
							 | 
						||
| 
								 | 
							
								    const range_type range = random::detail::subtract<result_type>()(max_value, min_value);
							 | 
						||
| 
								 | 
							
								    const base_result bmin = (eng.min)();
							 | 
						||
| 
								 | 
							
								    const base_unsigned brange =
							 | 
						||
| 
								 | 
							
								      random::detail::subtract<base_result>()((eng.max)(), (eng.min)());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(range == 0) {
							 | 
						||
| 
								 | 
							
								      return min_value;    
							 | 
						||
| 
								 | 
							
								    } else if(brange == range) {
							 | 
						||
| 
								 | 
							
								      // this will probably never happen in real life
							 | 
						||
| 
								 | 
							
								      // basically nothing to do; just take care we don't overflow / underflow
							 | 
						||
| 
								 | 
							
								      base_unsigned v = random::detail::subtract<base_result>()(eng(), bmin);
							 | 
						||
| 
								 | 
							
								      return random::detail::add<base_unsigned, result_type>()(v, min_value);
							 | 
						||
| 
								 | 
							
								    } else if(brange < range) {
							 | 
						||
| 
								 | 
							
								      // use rejection method to handle things like 0..3 --> 0..4
							 | 
						||
| 
								 | 
							
								      for(;;) {
							 | 
						||
| 
								 | 
							
								        // concatenate several invocations of the base RNG
							 | 
						||
| 
								 | 
							
								        // take extra care to avoid overflows
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //  limit == floor((range+1)/(brange+1))
							 | 
						||
| 
								 | 
							
								        //  Therefore limit*(brange+1) <= range+1
							 | 
						||
| 
								 | 
							
								        range_type limit;
							 | 
						||
| 
								 | 
							
								        if(range == (std::numeric_limits<range_type>::max)()) {
							 | 
						||
| 
								 | 
							
								          limit = range/(range_type(brange)+1);
							 | 
						||
| 
								 | 
							
								          if(range % (range_type(brange)+1) == range_type(brange))
							 | 
						||
| 
								 | 
							
								            ++limit;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          limit = (range+1)/(range_type(brange)+1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // We consider "result" as expressed to base (brange+1):
							 | 
						||
| 
								 | 
							
								        // For every power of (brange+1), we determine a random factor
							 | 
						||
| 
								 | 
							
								        range_type result = range_type(0);
							 | 
						||
| 
								 | 
							
								        range_type mult = range_type(1);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // loop invariants:
							 | 
						||
| 
								 | 
							
								        //  result < mult
							 | 
						||
| 
								 | 
							
								        //  mult <= range
							 | 
						||
| 
								 | 
							
								        while(mult <= limit) {
							 | 
						||
| 
								 | 
							
								          // Postcondition: result <= range, thus no overflow
							 | 
						||
| 
								 | 
							
								          //
							 | 
						||
| 
								 | 
							
								          // limit*(brange+1)<=range+1                   def. of limit       (1)
							 | 
						||
| 
								 | 
							
								          // eng()-bmin<=brange                          eng() post.         (2)
							 | 
						||
| 
								 | 
							
								          // and mult<=limit.                            loop condition      (3)
							 | 
						||
| 
								 | 
							
								          // Therefore mult*(eng()-bmin+1)<=range+1      by (1),(2),(3)      (4)
							 | 
						||
| 
								 | 
							
								          // Therefore mult*(eng()-bmin)+mult<=range+1   rearranging (4)     (5)
							 | 
						||
| 
								 | 
							
								          // result<mult                                 loop invariant      (6)
							 | 
						||
| 
								 | 
							
								          // Therefore result+mult*(eng()-bmin)<range+1  by (5), (6)         (7)
							 | 
						||
| 
								 | 
							
								          //
							 | 
						||
| 
								 | 
							
								          // Postcondition: result < mult*(brange+1)
							 | 
						||
| 
								 | 
							
								          //
							 | 
						||
| 
								 | 
							
								          // result<mult                                 loop invariant      (1)
							 | 
						||
| 
								 | 
							
								          // eng()-bmin<=brange                          eng() post.         (2)
							 | 
						||
| 
								 | 
							
								          // Therefore result+mult*(eng()-bmin) <
							 | 
						||
| 
								 | 
							
								          //           mult+mult*(eng()-bmin)            by (1)              (3)
							 | 
						||
| 
								 | 
							
								          // Therefore result+(eng()-bmin)*mult <
							 | 
						||
| 
								 | 
							
								          //           mult+mult*brange                  by (2), (3)         (4)
							 | 
						||
| 
								 | 
							
								          // Therefore result+(eng()-bmin)*mult <
							 | 
						||
| 
								 | 
							
								          //           mult*(brange+1)                   by (4)
							 | 
						||
| 
								 | 
							
								          result += static_cast<range_type>(static_cast<range_type>(random::detail::subtract<base_result>()(eng(), bmin)) * mult);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // equivalent to (mult * (brange+1)) == range+1, but avoids overflow.
							 | 
						||
| 
								 | 
							
								          if(mult * range_type(brange) == range - mult + 1) {
							 | 
						||
| 
								 | 
							
								              // The destination range is an integer power of
							 | 
						||
| 
								 | 
							
								              // the generator's range.
							 | 
						||
| 
								 | 
							
								              return(result);
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // Postcondition: mult <= range
							 | 
						||
| 
								 | 
							
								          // 
							 | 
						||
| 
								 | 
							
								          // limit*(brange+1)<=range+1                   def. of limit       (1)
							 | 
						||
| 
								 | 
							
								          // mult<=limit                                 loop condition      (2)
							 | 
						||
| 
								 | 
							
								          // Therefore mult*(brange+1)<=range+1          by (1), (2)         (3)
							 | 
						||
| 
								 | 
							
								          // mult*(brange+1)!=range+1                    preceding if        (4)
							 | 
						||
| 
								 | 
							
								          // Therefore mult*(brange+1)<range+1           by (3), (4)         (5)
							 | 
						||
| 
								 | 
							
								          // 
							 | 
						||
| 
								 | 
							
								          // Postcondition: result < mult
							 | 
						||
| 
								 | 
							
								          //
							 | 
						||
| 
								 | 
							
								          // See the second postcondition on the change to result. 
							 | 
						||
| 
								 | 
							
								          mult *= range_type(brange)+range_type(1);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // loop postcondition: range/mult < brange+1
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        // mult > limit                                  loop condition      (1)
							 | 
						||
| 
								 | 
							
								        // Suppose range/mult >= brange+1                Assumption          (2)
							 | 
						||
| 
								 | 
							
								        // range >= mult*(brange+1)                      by (2)              (3)
							 | 
						||
| 
								 | 
							
								        // range+1 > mult*(brange+1)                     by (3)              (4)
							 | 
						||
| 
								 | 
							
								        // range+1 > (limit+1)*(brange+1)                by (1), (4)         (5)
							 | 
						||
| 
								 | 
							
								        // (range+1)/(brange+1) > limit+1                by (5)              (6)
							 | 
						||
| 
								 | 
							
								        // limit < floor((range+1)/(brange+1))           by (6)              (7)
							 | 
						||
| 
								 | 
							
								        // limit==floor((range+1)/(brange+1))            def. of limit       (8)
							 | 
						||
| 
								 | 
							
								        // not (2)                                       reductio            (9)
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        // loop postcondition: (range/mult)*mult+(mult-1) >= range
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        // (range/mult)*mult + range%mult == range       identity            (1)
							 | 
						||
| 
								 | 
							
								        // range%mult < mult                             def. of %           (2)
							 | 
						||
| 
								 | 
							
								        // (range/mult)*mult+mult > range                by (1), (2)         (3)
							 | 
						||
| 
								 | 
							
								        // (range/mult)*mult+(mult-1) >= range           by (3)              (4)
							 | 
						||
| 
								 | 
							
								        //
							 | 
						||
| 
								 | 
							
								        // Note that the maximum value of result at this point is (mult-1),
							 | 
						||
| 
								 | 
							
								        // so after this final step, we generate numbers that can be
							 | 
						||
| 
								 | 
							
								        // at least as large as range.  We have to really careful to avoid
							 | 
						||
| 
								 | 
							
								        // overflow in this final addition and in the rejection.  Anything
							 | 
						||
| 
								 | 
							
								        // that overflows is larger than range and can thus be rejected.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // range/mult < brange+1  -> no endless loop
							 | 
						||
| 
								 | 
							
								        range_type result_increment =
							 | 
						||
| 
								 | 
							
								            generate_uniform_int(
							 | 
						||
| 
								 | 
							
								                eng,
							 | 
						||
| 
								 | 
							
								                static_cast<range_type>(0),
							 | 
						||
| 
								 | 
							
								                static_cast<range_type>(range/mult),
							 | 
						||
| 
								 | 
							
								                boost::mpl::true_());
							 | 
						||
| 
								 | 
							
								        if(std::numeric_limits<range_type>::is_bounded && ((std::numeric_limits<range_type>::max)() / mult < result_increment)) {
							 | 
						||
| 
								 | 
							
								          // The multiplcation would overflow.  Reject immediately.
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        result_increment *= mult;
							 | 
						||
| 
								 | 
							
								        // unsigned integers are guaranteed to wrap on overflow.
							 | 
						||
| 
								 | 
							
								        result += result_increment;
							 | 
						||
| 
								 | 
							
								        if(result < result_increment) {
							 | 
						||
| 
								 | 
							
								          // The addition overflowed.  Reject.
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if(result > range) {
							 | 
						||
| 
								 | 
							
								          // Too big.  Reject.
							 | 
						||
| 
								 | 
							
								          continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return random::detail::add<range_type, result_type>()(result, min_value);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    } else {                   // brange > range
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
							 | 
						||
| 
								 | 
							
								      typedef typename mpl::if_c<
							 | 
						||
| 
								 | 
							
								         std::numeric_limits<range_type>::is_specialized && std::numeric_limits<base_unsigned>::is_specialized
							 | 
						||
| 
								 | 
							
								         && (std::numeric_limits<range_type>::digits >= std::numeric_limits<base_unsigned>::digits),
							 | 
						||
| 
								 | 
							
								         range_type, base_unsigned>::type mixed_range_type;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								      typedef base_unsigned mixed_range_type;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      mixed_range_type bucket_size;
							 | 
						||
| 
								 | 
							
								      // it's safe to add 1 to range, as long as we cast it first,
							 | 
						||
| 
								 | 
							
								      // because we know that it is less than brange.  However,
							 | 
						||
| 
								 | 
							
								      // we do need to be careful not to cause overflow by adding 1
							 | 
						||
| 
								 | 
							
								      // to brange.  We use mixed_range_type throughout for mixed
							 | 
						||
| 
								 | 
							
								      // arithmetic between base_unsigned and range_type - in the case
							 | 
						||
| 
								 | 
							
								      // that range_type has more bits than base_unsigned it is always
							 | 
						||
| 
								 | 
							
								      // safe to use range_type for this albeit it may be more effient
							 | 
						||
| 
								 | 
							
								      // to use base_unsigned.  The latter is a narrowing conversion though
							 | 
						||
| 
								 | 
							
								      // which may be disallowed if range_type is a multiprecision type
							 | 
						||
| 
								 | 
							
								      // and there are no explicit converison operators.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if(brange == (std::numeric_limits<base_unsigned>::max)()) {
							 | 
						||
| 
								 | 
							
								        bucket_size = static_cast<mixed_range_type>(brange) / (static_cast<mixed_range_type>(range)+1);
							 | 
						||
| 
								 | 
							
								        if(static_cast<mixed_range_type>(brange) % (static_cast<mixed_range_type>(range)+1) == static_cast<mixed_range_type>(range)) {
							 | 
						||
| 
								 | 
							
								          ++bucket_size;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        bucket_size = static_cast<mixed_range_type>(brange + 1) / (static_cast<mixed_range_type>(range)+1);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      for(;;) {
							 | 
						||
| 
								 | 
							
								        mixed_range_type result =
							 | 
						||
| 
								 | 
							
								          random::detail::subtract<base_result>()(eng(), bmin);
							 | 
						||
| 
								 | 
							
								        result /= bucket_size;
							 | 
						||
| 
								 | 
							
								        // result and range are non-negative, and result is possibly larger
							 | 
						||
| 
								 | 
							
								        // than range, so the cast is safe
							 | 
						||
| 
								 | 
							
								        if(result <= static_cast<mixed_range_type>(range))
							 | 
						||
| 
								 | 
							
								          return random::detail::add<mixed_range_type, result_type>()(result, min_value);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef BOOST_MSVC
							 | 
						||
| 
								 | 
							
								#pragma warning(pop)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class Engine, class T>
							 | 
						||
| 
								 | 
							
								inline T generate_uniform_int(
							 | 
						||
| 
								 | 
							
								    Engine& eng, T min_value, T max_value,
							 | 
						||
| 
								 | 
							
								    boost::mpl::false_ /** is_integral<Engine::result_type> */)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uniform_int_float<Engine> wrapper(eng);
							 | 
						||
| 
								 | 
							
								    return generate_uniform_int(wrapper, min_value, max_value, boost::mpl::true_());
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class Engine, class T>
							 | 
						||
| 
								 | 
							
								inline T generate_uniform_int(Engine& eng, T min_value, T max_value)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    typedef typename Engine::result_type base_result;
							 | 
						||
| 
								 | 
							
								    return generate_uniform_int(eng, min_value, max_value,
							 | 
						||
| 
								 | 
							
								        boost::random::traits::is_integral<base_result>());
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * The class template uniform_int_distribution models a \random_distribution.
							 | 
						||
| 
								 | 
							
								 * On each invocation, it returns a random integer value uniformly
							 | 
						||
| 
								 | 
							
								 * distributed in the set of integers {min, min+1, min+2, ..., max}.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The template parameter IntType shall denote an integer-like value type.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								template<class IntType = int>
							 | 
						||
| 
								 | 
							
								class uniform_int_distribution
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
								    typedef IntType input_type;
							 | 
						||
| 
								 | 
							
								    typedef IntType result_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    class param_type
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    public:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        typedef uniform_int_distribution distribution_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /**
							 | 
						||
| 
								 | 
							
								         * Constructs the parameters of a uniform_int_distribution.
							 | 
						||
| 
								 | 
							
								         *
							 | 
						||
| 
								 | 
							
								         * Requires min <= max
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        explicit param_type(
							 | 
						||
| 
								 | 
							
								            IntType min_arg = 0,
							 | 
						||
| 
								 | 
							
								            IntType max_arg = (std::numeric_limits<IntType>::max)())
							 | 
						||
| 
								 | 
							
								          : _min(min_arg), _max(max_arg)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            BOOST_ASSERT(_min <= _max);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Returns the minimum value of the distribution. */
							 | 
						||
| 
								 | 
							
								        IntType a() const { return _min; }
							 | 
						||
| 
								 | 
							
								        /** Returns the maximum value of the distribution. */
							 | 
						||
| 
								 | 
							
								        IntType b() const { return _max; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Writes the parameters to a @c std::ostream. */
							 | 
						||
| 
								 | 
							
								        BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            os << parm._min << " " << parm._max;
							 | 
						||
| 
								 | 
							
								            return os;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Reads the parameters from a @c std::istream. */
							 | 
						||
| 
								 | 
							
								        BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            IntType min_in, max_in;
							 | 
						||
| 
								 | 
							
								            if(is >> min_in >> std::ws >> max_in) {
							 | 
						||
| 
								 | 
							
								                if(min_in <= max_in) {
							 | 
						||
| 
								 | 
							
								                    parm._min = min_in;
							 | 
						||
| 
								 | 
							
								                    parm._max = max_in;
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    is.setstate(std::ios_base::failbit);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return is;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Returns true if the two sets of parameters are equal. */
							 | 
						||
| 
								 | 
							
								        BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs)
							 | 
						||
| 
								 | 
							
								        { return lhs._min == rhs._min && lhs._max == rhs._max; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /** Returns true if the two sets of parameters are different. */
							 | 
						||
| 
								 | 
							
								        BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    private:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        IntType _min;
							 | 
						||
| 
								 | 
							
								        IntType _max;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Constructs a uniform_int_distribution. @c min and @c max are
							 | 
						||
| 
								 | 
							
								     * the parameters of the distribution.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * Requires: min <= max
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    explicit uniform_int_distribution(
							 | 
						||
| 
								 | 
							
								        IntType min_arg = 0,
							 | 
						||
| 
								 | 
							
								        IntType max_arg = (std::numeric_limits<IntType>::max)())
							 | 
						||
| 
								 | 
							
								      : _min(min_arg), _max(max_arg)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        BOOST_ASSERT(min_arg <= max_arg);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /** Constructs a uniform_int_distribution from its parameters. */
							 | 
						||
| 
								 | 
							
								    explicit uniform_int_distribution(const param_type& parm)
							 | 
						||
| 
								 | 
							
								      : _min(parm.a()), _max(parm.b()) {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**  Returns the minimum value of the distribution */
							 | 
						||
| 
								 | 
							
								    IntType min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
							 | 
						||
| 
								 | 
							
								    /**  Returns the maximum value of the distribution */
							 | 
						||
| 
								 | 
							
								    IntType max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**  Returns the minimum value of the distribution */
							 | 
						||
| 
								 | 
							
								    IntType a() const { return _min; }
							 | 
						||
| 
								 | 
							
								    /**  Returns the maximum value of the distribution */
							 | 
						||
| 
								 | 
							
								    IntType b() const { return _max; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Returns the parameters of the distribution. */
							 | 
						||
| 
								 | 
							
								    param_type param() const { return param_type(_min, _max); }
							 | 
						||
| 
								 | 
							
								    /** Sets the parameters of the distribution. */
							 | 
						||
| 
								 | 
							
								    void param(const param_type& parm)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        _min = parm.a();
							 | 
						||
| 
								 | 
							
								        _max = parm.b();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Effects: Subsequent uses of the distribution do not depend
							 | 
						||
| 
								 | 
							
								     * on values produced by any engine prior to invoking reset.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    void reset() { }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Returns an integer uniformly distributed in the range [min, max]. */
							 | 
						||
| 
								 | 
							
								    template<class Engine>
							 | 
						||
| 
								 | 
							
								    result_type operator()(Engine& eng) const
							 | 
						||
| 
								 | 
							
								    { return detail::generate_uniform_int(eng, _min, _max); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Returns an integer uniformly distributed in the range
							 | 
						||
| 
								 | 
							
								     * [param.a(), param.b()].
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    template<class Engine>
							 | 
						||
| 
								 | 
							
								    result_type operator()(Engine& eng, const param_type& parm) const
							 | 
						||
| 
								 | 
							
								    { return detail::generate_uniform_int(eng, parm.a(), parm.b()); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Writes the distribution to a @c std::ostream. */
							 | 
						||
| 
								 | 
							
								    BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_int_distribution, ud)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        os << ud.param();
							 | 
						||
| 
								 | 
							
								        return os;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /** Reads the distribution from a @c std::istream. */
							 | 
						||
| 
								 | 
							
								    BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_int_distribution, ud)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        param_type parm;
							 | 
						||
| 
								 | 
							
								        if(is >> parm) {
							 | 
						||
| 
								 | 
							
								            ud.param(parm);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return is;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Returns true if the two distributions will produce identical sequences
							 | 
						||
| 
								 | 
							
								     * of values given equal generators.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_int_distribution, lhs, rhs)
							 | 
						||
| 
								 | 
							
								    { return lhs._min == rhs._min && lhs._max == rhs._max; }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Returns true if the two distributions may produce different sequences
							 | 
						||
| 
								 | 
							
								     * of values given equal generators.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_int_distribution)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
								    IntType _min;
							 | 
						||
| 
								 | 
							
								    IntType _max;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // namespace random
							 | 
						||
| 
								 | 
							
								} // namespace boost
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // BOOST_RANDOM_UNIFORM_INT_HPP
							 |