This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD status.

### 2124. Seed sequence over-specified

Section: 28.5.3.2 [rand.req.seedseq] Status: NAD Submitter: Alberto Ganesh Barbati Opened: 2012-01-16 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [rand.req.seedseq].

View all issues with NAD status.

Discussion:

The seed sequence requirements described in 28.5.3.2 [rand.req.seedseq] appear to be over-specified. All seed sequence types are required to have a `result_type` nested type, a specific set of constructors, function members `size()` and `param()`, which are never used by the library. In fact, the only library components that actively use seed sequences are the random engines and all the engines need is the `generate()` member function. In particular, library components never attempts to construct seed sequence objects. These extraneous requirements are clearly written to describe the library provided type `seed_seq` type; while it's good that seed_seq has all those constructors and members, it's not a compelling reason to require a user-provided seed sequence type to implement all of them.

Suppose I want to write my own seed sequence class, this should do fine (and actually works as expected with libc++):

>     class my_seed_seq
>     {
>       /* internals */
>     public:
>       my_seed_seq(/* my own parameters */);

>       template <class It>
>       void generate(It first, It last);
>     };

>     my_seed_seq s(/* params */);
>     std::default_random_engine e(s);

The only reason to have these extra members would be to provide some support for generic serializability/persistence of seed sequence objects. I believe that would be out of the scope of the random library, so I doubt we will ever need those requirements in the future.

I therefore propose to remove all requirements from 28.5.3.2 [rand.req.seedseq] except for the presence of the `generate()` function.

[2012, Kona]

Move to Tenatively NAD. (Tentative as issue was not in pre-meeting mailing)

The 'overspecification', as such, was a deliberate intent to provide guarantees consumers of the whole random number framework may rely upon, especially in generic code. While the standard engines may be built without relying on these guarantees, this specification is part of a commitment to a broader framework, and Walter indicated future proposals in preparation for parallel generation of random numbers that may depend more inimately on these existing requirements.

Alisdair noted that the `result_type` typedef was a call-back to how we used to specify adaptable functors before TR1 `result_of` and the addition of `std::bind` and is probably not something we should be actively promoting in future libraries. However, it is too late to remove this requirement from seed sequences unless we are doing further surgery, as recommended by this issue.

Walter notes that the `result_type` protocol has not been formally deprecated by the standard. Alisdair replies that was the intent of deprecating the `bind_1st`/ `unary_function` set of templates in C++11, although we did not say anything about `result_type` in general.

Proposed resolution:

This wording is relative to the FDIS.

1. Edit 28.5.3.2 [rand.req.seedseq] p2 as indicated:

   > A class `S` satisfies the requirements of a seed sequence if the expressions shown in Table 115 are valid and have the indicated semantics, and if `S` also satisfies all other requirements of this section 28.5.3.2 [rand.req.seedseq]. In that Table and throughout this section:

   > 1. `T` is the type named by `S`'s associated `result_type`;
   > 2. `q` is a value of `S` and `r` is a possibly const value of `S`; and
   > 3. `ib` and `ie` are input iterators with an unsigned integer `value_type` of at least 32 bits;
   > 4. `rb` and `re` are mutable random access iterators with an unsigned integer `value_type` of at least 32 bits;
   > 5. `ob` is an output iterator; and
   > 6. `il` is a value of `initializer_list<T>`.

2. Ditto, in Table 115, remove all rows except the one describing `q.generate(rb, re)`:

   Table 115 — Seed sequence requirements
   Expression | Return type | Pre/Post-condition | Complexity
   --- | --- | --- | ---
   `S::result_type` | `T` | `T` is an unsigned integer type (6.8.2 [basic.fundamental]) of at least 32 bits. | compile-time
   `S()` |  | Creates a seed sequence with the same initial state as all other default-constructed seed sequences of type `S`. | constant
   `S(ib,ie)` |  | Creates a seed sequence having internal state that depends on some or all of the bits of the supplied sequence `[ib, ie)`. | `𝒪(ie - ib)`
   `S(il)` |  | Same as `S(il.begin(), il.end())`. | same as `S(il.begin(), il.end())`
   `q.generate(rb,re)` | `void` | Does nothing if `rb == re`. Otherwise, fills the supplied sequence `[rb, re)` with 32-bit quantities that depend on the sequence supplied to the constructor and possibly also depend on the history of `generate`'s previous invocations. | `𝒪(re - rb)`
   `r.size()` | `size_t` | The number of 32-bit units that would be copied by a call to `r.param`. | constant
   `r.param(ob)` | `void` | Copies to the given destination a sequence of 32-bit units that can be provided to the constructor of a second object of type `S`, and that would reproduce in that second object a state indistinguishable from the state of the first object. | `𝒪(r.size())`