home | help
std::seed_seq::generate(3)     C++ Standard Libary    std::seed_seq::generate(3)

NAME
     std::seed_seq::generate - std::seed_seq::generate

Synopsis
	template< class RandomIt >			(since C++11)
	void generate( RandomIt begin, RandomIt end );

	Fills  the  range  [begin, end) with unsigned integer values i, 0 ax i <
     232
	, based on the data originally	provided  in  the  constructor	of  this
     seed_seq. The
	produced values are distributed over the entire 32-bit range even if the
     initial
	values were strongly biased.

	The  following	algorithm  is  used (adapted from the initialization se-
     quence of the
	Mersenne Twister generator by Makoto Matsumoto and Takuji Nishimura, in-
     corporating
	the improvements made by Mutsuo Saito in 2007)

	  * If begin == end, do nothing. Otherwise,
	  * First, set each element of the output range to the value 0x8b8b8b8b.
	  * Transform the elements of the output range according to the  follow-
     ing algorithm:

	For k = 0,..., m - 1

	where m = max(s + 1, n)
	and n = end - begin
	and s = v.size()
	and v is the private container holding the values originally provided by
     the
	constructor of this seed_seq object,

	 1. begin[k + p] += r1
	 2. begin[k + q] += r2
	 3. begin[k] = r2,

	where p = (n - t) / 2
	and q = p + t
	and t = (n >= 623) ? 11 : (n >= 68) ? 7 : (n >= 39) ? 5 : (n >= 7) ? 3 :
     (n - 1) / 2
	and r1 = 1664525 * T(begin[k] ^ begin[k + p] ^ begin[k a 1])
	and T(x) = x ^ (x >> 27)
	and r2 = r1 + s if k == 0, r2 = r1 + k % n + v[k - 1] if 0 < k <=s, r2 =
     r1 + k % n
	if k > s.

	For k = m,..., m + n - 1,

	 1. begin[k + p] ^= r3
	 2. begin[k + q] ^= r4
	 3. begin[k] = r4

	where r3 = 1566083941 * T(begin[k] + begin[k + p] + begin[k - 1])
	and r4 = r3 - k % n

	where all calculations are performed modulo 232
	and where the indexing of the output range (begin[x]) is taken modulo n.

Parameters
		     mutable random-access iterators whose
	begin,	end  - std::iterator_traits<>::value_type is an unsigned integer
     type suitable
		     for storing 32-bit values

Type requirements
	-
	RandomIt must meet the requirements of LegacyRandomAccessIterator.

Return value
	None, the results are written to the [begin, end) range.

Exceptions
	Only throws if the operations on begin and end throw.

Example
     // Run this code

      #include <algorithm>
      #include <cassert>
      #include <cstdint>
      #include <iostream>
      #include <random>

      // Prototyping the main part of std::seed_seq...
      struct seed_seq
      {
	  std::vector<std::uint32_t> v;

	  seed_seq(std::initializer_list<std::uint32_t> const il) : v{il} {}

	  template <typename RandomIt>
	  void generate(RandomIt first, RandomIt last)
	  {
	      if (first == last)
		  return;
	      //
	      // Assuming v = {1,2,3,4,5} and distance(first, last) == 10.
	      //
	      // Step 1: fill with 0x8b8b8b8b
	      //  seeds  =  {2341178251,  2341178251,  2341178251,   2341178251,
     2341178251,
	      //	    2341178251,   2341178251,	2341178251,  2341178251,
     2341178251 }
	      //
	      std::fill(first, last, 0x8b8b8b8b);
	      //
	      // Step 2:
	      // n = 10, s = 5, t = 3, p = 3, q = 6, m = 10
	      //
	      const std::uint32_t n = last - first;
	      const std::uint32_t s = v.size();
	      const std::uint32_t t = (n < 7) ? (n - 1) / 2
				    : (n < 39) ? 3
				    : (n < 68) ? 5
				    : (n < 623) ? 7
				    : 11;
	      const std::uint32_t p = (n - t) / 2;
	      const std::uint32_t q = p + t;
	      const std::uint32_t m = std::max(s + 1, n);
	      //
	      // First iteration, k = 0; r1 = 1371501266, r2 = 1371501271
	      //
	      //  seeds  =  {1371501271,  2341178251,  2341178251,   3712679517,
     2341178251,
	      //	    2341178251,   3712679522,	2341178251,  2341178251,
     2341178251 }
	      //
	      // Iterations from k = 1 to k = 5 (r2 = r1 + k % n + v[k - 1])
	      //
	      // r1 = 2786190137, 3204727651, 4173325571, 1979226628, 401983366
	      // r2 = 2786190139, 3204727655, 4173325577, 1979226636, 401983376
	      //
	      //  seeds  =  {3350727907,  3188173515,  3204727655,   4173325577,
     1979226636,
	      //	     401983376,   3591037797,	2811627722,  1652921976,
     2219536532 }
	      //
	      // Iterations from k = 6 to k = 9 (r2 = r1 + k % n)
	      //
	      // r1 = 2718637909, 1378394210, 2297813071, 1608643617
	      // r2 = 2718637915, 1378394217, 2297813079, 1608643626
	      //
	      //  seeds  =  {  434154821,  1191019290,	3237041891,  1256752498,
     4277039715,
	      //	    2010627002,   2718637915,	1378394217,  2297813079,
     1608643626 }
	      //
	      auto begin_mod = [first, n](std::uint32_t u) -> decltype(*first)&
	      {
		  return first[u % n]; // i.e. begin[x] is taken modulo n
	      };
	      auto T = [](std::uint32_t x) { return x ^ (x >> 27); };

	      for (std::uint32_t k = 0, r1, r2; k < m; ++k)
	      {
		  r1 = 1664525 * T(begin_mod(k) ^ begin_mod(k + p) ^ begin_mod(k
     - 1));
		  r2 = (k == 0) ? r1 + s
		     : (k <= s) ? r1 + k % n + v[k - 1]
		     :		  r1 + k % n;
		  begin_mod(k + p) += r1;
		  begin_mod(k + q) += r2;
		  begin_mod(k) = r2;
	      }
	      //
	      // Step 3
	      // iterations from k = 10 to k = 19, using ^= to modify the output
	      //
	      // r1 = 1615303485, 3210438310, 893477041, 2884072672, 1918321961,
	      // r2 = 1615303485, 3210438309, 893477039, 2884072669, 1918321957
	      //
	      //  seeds  =  {  303093272,  3210438309,	 893477039,  2884072669,
     1918321957,
	      //	    1117182731,   1772877958,	2669970405,  3182737656,
     4094066935 }
	      //
	      // r1 =  423054846, 46783064, 3904109085, 1534123446, 1495905687
	      // r2 =  423054841, 46783058, 3904109078, 1534123438, 1495905678
	      //
	      // seeds	=  {  4204997637,  4246533866,	1856049002,  1129615051,
     690460811,
	      //	     1075771511,     46783058,	3904109078,  1534123438,
     1495905678 }
	      //
	      for (std::uint32_t k = m, r3, r4; k < m + n; ++k)
	      {
		  r3 = 1566083941 * T(begin_mod(k) +  begin_mod(k  +  p)  +  be-
     gin_mod(k - 1));
		  r4 = r3 - k % n;
		  begin_mod(k+p) ^= r3;
		  begin_mod(k+q) ^= r4;
		  begin_mod(k) = r4;
	      }
	  }
      };

      int main()
      {
	  const auto input = std::initializer_list<std::uint32_t>{1,2,3,4,5};
	  const auto output_size = 10;

	  // using std version of seed_seq
	  std::seed_seq seq(input);
	  std::vector<std::uint32_t> seeds(output_size);
	  seq.generate(seeds.begin(), seeds.end());
	  for (const std::uint32_t n : seeds)
	      std::cout << n << '\n';

	  // using custom version of seed_seq
	  seed_seq seq2(input);
	  std::vector<std::uint32_t> seeds2(output_size);
	  seq2.generate(seeds2.begin(), seeds2.end());

	  assert(seeds == seeds2);
      }

Output:
      4204997637
      4246533866
      1856049002
      1129615051
      690460811
      1075771511
      46783058
      3904109078
      1534123438
      1495905678

http://cppreference.com 	   2024.06.10	      std::seed_seq::generate(3)

home | help