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

### 3150. `UniformRandomBitGenerator` should validate `min` and `max`

Section: 28.5.3.3 [rand.req.urng] Status: C++20 Submitter: Casey Carter Opened: 2018-08-09 Last modified: 2021-02-25

Priority: 3

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

View all issues with C++20 status.

Discussion:

28.5.3.3 [rand.req.urng] paragraph 2 specifies axioms for the `UniformRandomBitGenerator` concept:

> 2 Let `g` be an object of type `G`. `G` models `UniformRandomBitGenerator` only if

> (2.1) — both `G::min()` and `G::max()` are constant expressions (7.7 [expr.const]),

> (2.2) — `G::min() < G::max()`,

> (2.3) — `G::min() <= g()`,

> (2.4) — `g() <= G::max()`, and

> (2.5) — `g()` has amortized constant complexity.

Bullets 2.1 and 2.2 are both compile-time requirements that ought to be validated by the concept.

[2018-08-20 Priority set to 3 after reflector discussion]

Previous resolution [SUPERSEDED]:

> This wording is relative to N4791.

> 1. Modify 28.5.3.3 [rand.req.urng] as follows:

>    > 1 A uniform random bit generator `g` of type `G` is a function object returning unsigned integer values such that each value in the range of possible results has (ideally) equal probability of being returned. [Note: The degree to which `g`'s results approximate the ideal is often determined statistically.—end note]

>    > >     template<auto> struct require-constant; // exposition-only

>    > >     template<class G>
>    > >       concept UniformRandomBitGenerator =
>    > >         Invocable<G&> && UnsignedIntegral<invoke_result_t<G&>> &&
>    > >         requires {
>    > >           { G::min() } -> Same<invoke_result_t<G&>>;
>    > >           { G::max() } -> Same<invoke_result_t<G&>>;
>    > >           typename require-constant<G::min()>;
>    > >           typename require-constant<G::max()>;
>    > >           requires G::min() < G::max();
>    > >         };

>    > 2 Let `g` be an object of type `G`. `G` models `UniformRandomBitGenerator` only if

>    > (2.1) — both `G​::​min()` and `G​::​max()` are constant expressions (7.7 [expr.const]),

>    > (2.2) — `G​::​min() < G​::​max()`,

>    > (2.3) — `G​::​min() <= g()`,

>    > (2.4) — `g() <= G​::​max()`, and

>    > (2.5) — `g()` has amortized constant complexity.

>    > 3 A class `G` meets the uniform random bit generator requirements if `G` models `UniformRandomBitGenerator`, `invoke_result_t<G&>` is an unsigned integer type (6.8.2 [basic.fundamental]), and `G` provides a nested typedef-name `result_type` that denotes the same type as `invoke_result_t<G&>`.

[2020-02-13; Prague]

LWG provided some improved wording.

[2020-02 Status to Immediate on Thursday night in Prague.]

Proposed resolution:

This wording is relative to N4849.

1. Modify 28.5.3.3 [rand.req.urng] as follows:

   > 1 A uniform random bit generator `g` of type `G` is a function object returning unsigned integer values such that each value in the range of possible results has (ideally) equal probability of being returned. [Note: The degree to which `g`'s results approximate the ideal is often determined statistically.—end note]

   > >     template<class G>
   > >       concept uniform_random_bit_generator =
   > >         invocable<G&> && unsigned_integral<invoke_result_t<G&>> &&
   > >         requires {
   > >           { G::min() } -> same_as<invoke_result_t<G&>>;
   > >           { G::max() } -> same_as<invoke_result_t<G&>>;
   > >           requires bool_constant<(G::min() < G::max())>::value;
   > >         };

   > -2- Let `g` be an object of type `G`. `G` models `uniform_random_bit_generator` only if

   > (2.1) — both `G​::​min()` and `G​::​max()` are constant expressions (7.7 [expr.const]),

   > (2.2) — `G​::​min() < G​::​max()`,

   > (2.3) — `G​::​min() <= g()`,

   > (2.4) — `g() <= G​::​max()`, and

   > (2.5) — `g()` has amortized constant complexity.

   > 3 A class `G` meets the uniform random bit generator requirements if `G` models `uniform_random_bit_generator`, `invoke_result_t<G&>` is an unsigned integer type (6.8.2 [basic.fundamental]), and `G` provides a nested typedef-name `result_type` that denotes the same type as `invoke_result_t<G&>`.