shuffle_output.hpp

来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 176 行

HPP
176
字号
/* boost random/shuffle_output.hpp header file * * Copyright Jens Maurer 2000-2001 * 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: shuffle_output.hpp,v 1.1.1.2 2004/11/20 10:49:20 spion Exp $ * * Revision history *  2001-02-18  moved to individual header files */#ifndef BOOST_RANDOM_SHUFFLE_OUTPUT_HPP#define BOOST_RANDOM_SHUFFLE_OUTPUT_HPP#include <iostream>#include <algorithm>     // std::copy#include <cassert>#include <boost/config.hpp>#include <boost/limits.hpp>#include <boost/static_assert.hpp>#include <boost/cstdint.hpp>#include <boost/random/linear_congruential.hpp>namespace boost {namespace random {// Carter Bays and S.D. Durham 1979template<class UniformRandomNumberGenerator, int k,#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS  typename UniformRandomNumberGenerator::result_type #else  uint32_t#endif  val = 0>class shuffle_output{public:  typedef UniformRandomNumberGenerator base_type;  typedef typename base_type::result_type result_type;  BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);  BOOST_STATIC_CONSTANT(int, buffer_size = k);  shuffle_output() : _rng() { init(); }#if defined(BOOST_MSVC) && _MSC_VER <= 1200  // MSVC does not implicitly generate the copy constructor here  shuffle_output(const shuffle_output & x)    : _rng(x._rng), y(x.y) { std::copy(x.v, x.v+k, v); }#endif  template<class T>  explicit shuffle_output(T seed) : _rng(seed) { init(); }  explicit shuffle_output(const base_type & rng) : _rng(rng) { init(); }  template<class It> shuffle_output(It& first, It last)    : _rng(first, last) { init(); }  void seed() { _rng.seed(); init(); }  template<class T>  void seed(T s) { _rng.seed(s); init(); }  template<class It> void seed(It& first, It last)  {    _rng.seed(first, last);    init();  }  const base_type& base() const { return _rng; }  result_type operator()() {    // calculating the range every time may seem wasteful.  However, this    // makes the information locally available for the optimizer.    result_type range = (max)()-(min)()+1;    int j = k*(y-(min)())/range;    // assert(0 <= j && j < k);    y = v[j];    v[j] = _rng();    return y;  }  result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.min)(); }  result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.max)(); }  static bool validation(result_type x) { return val == x; }#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS  template<class CharT, class Traits>  friend std::basic_ostream<CharT,Traits>&  operator<<(std::basic_ostream<CharT,Traits>& os, const shuffle_output& s)  {    os << s._rng << " " << s.y << " ";    for(int i = 0; i < s.buffer_size; ++i)      os << s.v[i] << " ";    return os;  }  template<class CharT, class Traits>  friend std::basic_istream<CharT,Traits>&  operator>>(std::basic_istream<CharT,Traits>& is, shuffle_output& s)  {    is >> s._rng >> std::ws >> s.y >> std::ws;    for(int i = 0; i < s.buffer_size; ++i)      is >> s.v[i] >> std::ws;    return is;  }#endif  friend bool operator==(const shuffle_output& x, const shuffle_output& y)  { return x._rng == y._rng && x.y == y.y && std::equal(x.v, x.v+k, y.v); }  friend bool operator!=(const shuffle_output& x, const shuffle_output& y)  { return !(x == y); }#else  // Use a member function; Streamable concept not supported.  bool operator==(const shuffle_output& rhs) const  { return _rng == rhs._rng && y == rhs.y && std::equal(v, v+k, rhs.v); }  bool operator!=(const shuffle_output& rhs) const  { return !(*this == rhs); }#endifprivate:  void init()  {#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS    BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_integer);#endif    result_type range = (max)()-(min)();    assert(range > 0);      // otherwise there would be little choice    if(static_cast<unsigned long>(k * range) <        static_cast<unsigned long>(range))  // not a sufficient condition      // likely overflow with bucket number computation      assert(!"overflow will occur");    // we cannot use std::generate, because it uses pass-by-value for _rng    for(result_type * p = v; p != v+k; ++p)      *p = _rng();    y = _rng();  }  base_type _rng;  result_type v[k];  result_type y;};#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION//  A definition is required even for integral static constantstemplate<class UniformRandomNumberGenerator, int k, #ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS  typename UniformRandomNumberGenerator::result_type #else  uint32_t#endif  val>const bool shuffle_output<UniformRandomNumberGenerator, k, val>::has_fixed_range;template<class UniformRandomNumberGenerator, int k, #ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS  typename UniformRandomNumberGenerator::result_type #else  uint32_t#endif  val>const int shuffle_output<UniformRandomNumberGenerator, k, val>::buffer_size;#endif} // namespace random// validation by experiment from Harry Erwin's generator.h (private e-mail)typedef random::shuffle_output<    random::linear_congruential<uint32_t, 1366, 150889, 714025, 0>,  97, 139726> kreutzer1986;} // namespace boost#endif // BOOST_RANDOM_SHUFFLE_OUTPUT_HPP

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?