~ubuntu-branches/ubuntu/breezy/aqsis/breezy

« back to all changes in this revision

Viewing changes to boost/boost/random/shuffle_output.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Will Newton
  • Date: 2004-12-07 20:06:49 UTC
  • Revision ID: james.westby@ubuntu.com-20041207200649-fccswkrvp4oc8lmn
Tags: upstream-0.9.3
ImportĀ upstreamĀ versionĀ 0.9.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* boost random/shuffle_output.hpp header file
 
2
 *
 
3
 * Copyright Jens Maurer 2000-2001
 
4
 * Permission to use, copy, modify, sell, and distribute this software
 
5
 * is hereby granted without fee provided that the above copyright notice
 
6
 * appears in all copies and that both that copyright notice and this
 
7
 * permission notice appear in supporting documentation,
 
8
 *
 
9
 * Jens Maurer makes no representations about the suitability of this
 
10
 * software for any purpose. It is provided "as is" without express or
 
11
 * implied warranty.
 
12
 *
 
13
 * See http://www.boost.org for most recent version including documentation.
 
14
 *
 
15
 * $Id: shuffle_output.hpp,v 1.1 2004/02/27 03:16:46 pseudonym Exp $
 
16
 *
 
17
 * Revision history
 
18
 *  2001-02-18  moved to individual header files
 
19
 */
 
20
 
 
21
#ifndef BOOST_RANDOM_SHUFFLE_OUTPUT_HPP
 
22
#define BOOST_RANDOM_SHUFFLE_OUTPUT_HPP
 
23
 
 
24
#include <iostream>
 
25
#include <algorithm>     // std::copy
 
26
#include <cassert>
 
27
#include <boost/config.hpp>
 
28
#include <boost/limits.hpp>
 
29
#include <boost/static_assert.hpp>
 
30
#include <boost/cstdint.hpp>
 
31
#include <boost/random/linear_congruential.hpp>
 
32
 
 
33
namespace boost {
 
34
namespace random {
 
35
 
 
36
// Carter Bays and S.D. Durham 1979
 
37
template<class UniformRandomNumberGenerator, int k,
 
38
#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
 
39
  typename UniformRandomNumberGenerator::result_type 
 
40
#else
 
41
  uint32_t
 
42
#endif
 
43
  val = 0>
 
44
class shuffle_output
 
45
{
 
46
public:
 
47
  typedef UniformRandomNumberGenerator base_type;
 
48
  typedef typename base_type::result_type result_type;
 
49
 
 
50
  BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
 
51
  BOOST_STATIC_CONSTANT(int, buffer_size = k);
 
52
 
 
53
  shuffle_output() : _rng() { init(); }
 
54
#if defined(BOOST_MSVC) && _MSC_VER <= 1200
 
55
  // MSVC does not implicitly generate the copy constructor here
 
56
  shuffle_output(const shuffle_output & x)
 
57
    : _rng(x._rng), y(x.y) { std::copy(x.v, x.v+k, v); }
 
58
#endif
 
59
  template<class T>
 
60
  explicit shuffle_output(T seed) : _rng(seed) { init(); }
 
61
  explicit shuffle_output(const base_type & rng) : _rng(rng) { init(); }
 
62
  template<class It> shuffle_output(It& first, It last)
 
63
    : _rng(first, last) { init(); }
 
64
  template<class T>
 
65
  void seed(T s) { _rng.seed(s); init(); }
 
66
  template<class It> void seed(It& first, It last)
 
67
  {
 
68
    _rng.seed(first, last);
 
69
    init();
 
70
  }
 
71
 
 
72
  const base_type& base() const { return _rng; }
 
73
 
 
74
  result_type operator()() {
 
75
    // calculating the range every time may seem wasteful.  However, this
 
76
    // makes the information locally available for the optimizer.
 
77
    result_type range = max()-min()+1;
 
78
    int j = k*(y-min())/range;
 
79
    // assert(0 <= j && j < k);
 
80
    y = v[j];
 
81
    v[j] = _rng();
 
82
    return y;
 
83
  }
 
84
 
 
85
  result_type min() const { return _rng.min(); }
 
86
  result_type max() const { return _rng.max(); }
 
87
  static bool validation(result_type x) { return val == x; }
 
88
 
 
89
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
 
90
 
 
91
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
 
92
  template<class CharT, class Traits>
 
93
  friend std::basic_ostream<CharT,Traits>&
 
94
  operator<<(std::basic_ostream<CharT,Traits>& os, const shuffle_output& s)
 
95
  {
 
96
    os << s._rng << " " << s.y << " ";
 
97
    for(int i = 0; i < s.buffer_size; ++i)
 
98
      os << s.v[i] << " ";
 
99
    return os;
 
100
  }
 
101
 
 
102
  template<class CharT, class Traits>
 
103
  friend std::basic_istream<CharT,Traits>&
 
104
  operator>>(std::basic_istream<CharT,Traits>& is, shuffle_output& s)
 
105
  {
 
106
    is >> s._rng >> std::ws >> s.y >> std::ws;
 
107
    for(int i = 0; i < s.buffer_size; ++i)
 
108
      is >> s.v[i] >> std::ws;
 
109
    return is;
 
110
  }
 
111
#endif
 
112
 
 
113
  friend bool operator==(const shuffle_output& x, const shuffle_output& y)
 
114
  { return x._rng == y._rng && x.y == y.y && std::equal(x.v, x.v+k, y.v); }
 
115
  friend bool operator!=(const shuffle_output& x, const shuffle_output& y)
 
116
  { return !(x == y); }
 
117
#else
 
118
  // Use a member function; Streamable concept not supported.
 
119
  bool operator==(const shuffle_output& rhs) const
 
120
  { return _rng == rhs._rng && y == rhs.y && std::equal(v, v+k, rhs.v); }
 
121
  bool operator!=(const shuffle_output& rhs) const
 
122
  { return !(*this == rhs); }
 
123
#endif
 
124
private:
 
125
  void init()
 
126
  {
 
127
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
 
128
    BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_integer);
 
129
#endif
 
130
    result_type range = max()-min();
 
131
    assert(range > 0);      // otherwise there would be little choice
 
132
    if(static_cast<unsigned long>(k * range) < 
 
133
       static_cast<unsigned long>(range))  // not a sufficient condition
 
134
      // likely overflow with bucket number computation
 
135
      assert(!"overflow will occur");
 
136
 
 
137
    // we cannot use std::generate, because it uses pass-by-value for _rng
 
138
    for(result_type * p = v; p != v+k; ++p)
 
139
      *p = _rng();
 
140
    y = _rng();
 
141
  }
 
142
 
 
143
  base_type _rng;
 
144
  result_type v[k];
 
145
  result_type y;
 
146
};
 
147
 
 
148
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 
149
//  A definition is required even for integral static constants
 
150
template<class UniformRandomNumberGenerator, int k, 
 
151
#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
 
152
  typename UniformRandomNumberGenerator::result_type 
 
153
#else
 
154
  uint32_t
 
155
#endif
 
156
  val>
 
157
const bool shuffle_output<UniformRandomNumberGenerator, k, val>::has_fixed_range;
 
158
 
 
159
template<class UniformRandomNumberGenerator, int k, 
 
160
#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
 
161
  typename UniformRandomNumberGenerator::result_type 
 
162
#else
 
163
  uint32_t
 
164
#endif
 
165
  val>
 
166
const int shuffle_output<UniformRandomNumberGenerator, k, val>::buffer_size;
 
167
#endif
 
168
 
 
169
} // namespace random
 
170
 
 
171
// validation by experiment from Harry Erwin's generator.h (private e-mail)
 
172
typedef random::shuffle_output<
 
173
    random::linear_congruential<uint32_t, 1366, 150889, 714025, 0>,
 
174
  97, 139726> kreutzer1986;
 
175
 
 
176
 
 
177
} // namespace boost
 
178
 
 
179
#endif // BOOST_RANDOM_SHUFFLE_OUTPUT_HPP