Boost logo

Boost :

From: Oliver Kullmann (O.Kullmann_at_[hidden])
Date: 2004-06-22 18:24:01


Hi,

following the request for some improved documentation
in my first e-mail (illustrated by some "case study" from a student's
experience) I would like to propose to include the
following class template RandomGeneratorInterval
into the documentation of the random number library
(a first draft, more explanations
should be added; of course, names can be changed).
It solves the task from my previous e-mail, and seems to
me a very typical first use of the library:

  template <class bgt = boost::minstd_rand, class dt = boost::uniform_int<> >
  class RandomGeneratorInterval {
  public :
    typedef bgt base_generator_type;
    typedef dt distribution_type;
    typedef boost::variate_generator<base_generator_type, distribution_type> generator_type;
    typedef typename generator_type::result_type interval_type;
    typedef typename base_generator_type::result_type seed_type;
    RandomGeneratorInterval(interval_type min, interval_type max) : min(min), max(max) {}
    generator_type operator() (seed_type seed = 1) const {
      assert(seed != 0);
      return generator_type(base_generator_type(seed), distribution_type(min, max));
    }
  private :
    const interval_type min, max;
  };
  // An object rgi defined by "RandomGeneratorInterval rgi(min, max)" can create a random number generator g via g = rgi(seed).
  // Random numbers in the interval from min to max then are created with g().
  // It is g() of type interval_type as well as min and max, while seed is of type seed_type; g itself is of type generator_type.
  // g is a model of a uniform random number generator (even a model of a pseudo-random number generator?!).

Examples for usage are

  typedef Algorithms::RandomGeneratorInterval<> RI;
  RI rgi(10,20);
  RI::generator_type g1 = rgi(456);
  RI::generator_type g2 = rgi();
  RI::generator_type g3 = rgi(1);
  assert(g1.min() == 10);
  assert(g1.max() == 20);
  assert(g1() == 10);
  assert(g1() == 18);
  assert(g1() == 12);
  assert(g2() == 10);
  assert(g2() == 10);
  assert(g2() == 16);
  assert(g3() == 10);
  assert(g3() == 10);
  assert(g3() == 16);
  // Attention: std::cout << g1() << " " << g1() results in implementation-defined behaviour (could be "10 18" or "18 12") !

(The last line seems a typical trap to me one has to be aware of, and thus it seems worth to
be included.)

Does the above code look reasonable?!

Oliver


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk