---
title: "P3791R1: constexpr (deterministic) random"
document: P3791R1
date: 2026-07-15
audience: LWG Library
reply-to:
  - "Hana Dusíková"
---

Number:

P3791R1

2026-07-15

[Library Evolution](mailto:Library Evolution (YOU-NEED-JAVASCRIPT-ENABLED) #TGlicmFyeSZuYnNwO0V2b2x1dGlvbiA8bGliLWV4dEBsaXN0cy5pc29jcHAub3JnPj9zdWJqZWN0PVAzNzkxUjE6IGNvbnN0ZXhwciAoZGV0ZXJtaW5pc3RpYykgcmFuZG9t)

Target:

C++29

Author:

[Hana Dusíková](mailto:hana dusikova (YOU-NEED-JAVASCRIPT-ENABLED) #SGFuYStEdXMlQzMlQURrb3YlQzMlQTEgPGhhbmlja2FAaGFuaWNrYS5uZXQ+P3N1YmplY3Q9UDM3OTFSMTogY29uc3RleHByIChkZXRlcm1pbmlzdGljKSByYW5kb20=)

---

◀︎

# P3791R1: constexpr (deterministic) random

This paper proposes making all **deterministic** algorithms and types associated with *random number generators* constant evaluatable. This paper doesn't propose making `random_device` type, `rand()` and `srand()` `constexpr` functions as these are not deterministic. Your builds won't be nondeterministic if this paper is merged into the standard.

## Changes

- [R0](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3791r0.html) → [R1](https://wg21.link/p3791r1): Paper was reviewed by LWG and voted 6/1/2 to be moved to straw poll pages during Brno meeting. During the review a concern was stated about implementability, I voluntarily withdraw the paper to provide adequate response to the concerns. This revision contains it in updated section Implementation experience. Otherwise the paper is unchanged and ready to move forward.

## Motivation

Algorithms `shuffle`, `sample` are useful even in compile time, same applies to random distribution types which are fully deterministic.

Making these functions `constexpr` limits the need for users to reimplement these and use `if consteval`, limiting number of errors due duplication of code.

### Probabilistic data structures

Special data structures types which use minimal amount of memory to classify items. They need [random sampling](https://en.wikipedia.org/wiki/Count–min_sketch). Users shouldn't reimplement sampling algorithms just because they can't use `std::ranges::sample`.

```
constexpr sample_to_sketch(std::span<const T> items, sketch<T> & sk) noexcept {
	// BEFORE: constructing object without non-constexpr constructor in constant evaluation
	// AFTER:  fine
	auto engine = std::mt19937_64{/* default seed is fine*/};
	// BEFORE: error: calling a non-constexpr function in constant evaluation
	// AFTER:  fine
	std::ranges::sample(items, std::insert_iterator(sk), sk.capacity(), engine); 
}
```

### Consteval tests

Constant evaluatability of more code opens doors to run tests during compilation with constant evaluator, which also checks for undefined behaviour. When we will be able to measure proper path test coverage, including boundaries which introduce undefined behaviour in code. Reaching 100% such path coverage will allow us to detect all possible UB occurences. If there is still some UB reachable, constant evaluator will detect during test evaluation and fail to evaluate.

## Implementation experience

All types and algorithms touched by this proposal are already `template`-ed. Making these `constexpr` is mostly exercise in marking these with keyword `constexpr`.

TL;DR of next subsection: once you have `constexpr <cmath>` then after only `constexpr` sprinkling in both libc++ and libstdc++'s `<random>` you have a functional implementation of this paper [successfully evaluating](https://compiler-explorer.com/z/5bdj95qs9). Also the implementations both returns exactly [same results during runtime and compile time](https://compiler-explorer.com/z/3naaWrrro).

### Response to concerns state during LWG review in Brno

During the LWG review in Brno the paper was approved to go to plenary, but some authors were concerned about this change, as no implementation provides full `constexpr <cmath` implementation. I have voluntarily withdraw the paper from going to plenary in order to provide a material evidence about the implementability. One of the concerns were me not testing the newer `std::poisson_distribution`.

Jonathan [sent me a code snippet](https://godbolt.org/z/vPcvvrzvj) and said he will be less concerned if the code he sent passes constant evaluation. The code now works as the experimental hana-clang contains the change.

#### libc++

In order to prove the paper is only sprinkling of `constexpr` I have prototyped `constexpr <cmath>` by implementing the necessary builtins, and marking all the functionality with `constexpr`. [The change](https://github.com/hanickadot/llvm-project/commit/9a3c3b135ca12d08df62f5f2646d53fc926bd654) containing only `<cmath>` and compiler evaluator changes is available on my github.

As the next step I have just sprinkled the `constexpr` around in <random> header (and internal `__random/FUNCTIONALITY.h` headers), [the change is also available](https://github.com/hanickadot/llvm-project/commit/4c193bda2f14b6d29a4f568bafc7b0427cafb5f0) on my github.

As you can now sea, the change is not complex. You can experiment with the implementation on [the Compiler Explorer](https://compiler-explorer.com/z/Evfjax5c4) where you can see complex example based on Jonathan's code which evalautes **each distributions** (including Poisson) with **every generator** available by the standard.

##### Unrelated issues found during implementation

As I was implementing and evaluating the code, I have noticed that some of libc++'s `<random>` functionality is using `#include <cmath>` instead of relying on internal `__math/FUNCTION.h`, and used unqualified names of math functions. Which on my platform (MacOS) lead to selection of function declarations in system's `math.h`. Which can't be marked `constexpr` and their own builtins are independently defined in clang's `builtin.td`.

By fixing the unqualified lookup and inclusion of right internal header. The updated `<random>` is no longer have dependency on the system header and instead it uses explicit builtins instead. The change is [also available](https://github.com/hanickadot/llvm-project/commit/80ab636e7cd6162fad78729f4d3babc74cd3e512) to see on my github.

#### libstdc++

Excited about perceived simplicity I went to look into libstdc++ implementation in GCC. I tried to use GCC's `-fimplicit-constexpr` option and see if I run only into `<cmath>` not being defined issues. Some of the functions of libstdc++'s `<random>` are defined outside of their class definition and [these functions are not implicitly inline](https://eel.is/c++draft/class.mfct#1.sentence-1), and they are not made implicitly `constexpr` by the switch which makes only inline functions implicitly `constexpr`.

So I took whole libstdc++'s `<random>` and its dependencies and put it all into the source editor of the Compiler Explorer and start making these functions constexpr manually, all of which was observed by (next to me sitting in audience on [ACCU on Sea](https://accuonsea.uk) conference) Matt Godbolt (the author of the Godbolt Compiler Explorer) with a horror in his eyes accompanied with a question *"how (incomprehensible) are you using it?"* later followed by a message *"Banananananananana"* (in our private discord conversation) as he was probably calculating how much this exercise cost him on the compute (which was a negligible amount of the compute used by large language models about which was Andrei Alexandrescu keynoting on the stage few meters from us). And once I start reaching first errors due `<math.h>`'s symbols not being defined I moved my focus on the conference instead.

A few weeks later I got the idea to [backport](https://github.com/hanickadot/llvm-project/commit/14dae7470d561316f461d70e2c969ea818794612) my `-fimplicit-constexpr` to hana-clang. It's a stronger version than GCC's (it makes every function implicitly `constexpr`). I made it while back as a PR for the upstream, some maintainers requested [a RFC](https://discourse.llvm.org/t/rfc-fimplicit-constexpr/85963) which was later sadly rejected as it's a niche functionality. Equiped with this in the hana-clang, I could finally try to run [the same test code](https://compiler-explorer.com/z/Evfjax5c4) I tried with libc++.

I ran into a problem the functionality was using `math.h` instead, and these builtins I didn't make `constexpr` in my clang. So I have needed to [modify my clang](https://github.com/llvm/llvm-project/commit/44218f7c1ed83bcb9f343fe0dfe1954cc7d7747d) to make these *normal-function-looking-builtins* also `constexpr`. After a tiny change I tried again, and ... [as you can see, it worked and flawlessly](https://compiler-explorer.com/z/oroY56T5T).

#### Does it return same results?

After I published this research on LWG mailing list, I talked with Tomasz who asked me *"Does it give same results?"* to which I answered with *"I don't see reason why it shouldn't"* and sent him [a quick test code](https://compiler-explorer.com/z/YeMfYqf4T) I made with Poisson distribution. Which shows the result is same.

I have made also [a test](https://compiler-explorer.com/z/3naaWrrro) which again tests all the distributions and engines called multiple times to return same result in runtime and compile time.

### Research of MSSTL

Similar situation as in other two implementations, all defined in [<random> header file](https://github.com/microsoft/STL/blob/e59dc201d19a57484d9e309e54ad66ef5055fff3/stl/inc/random#L30), but there are few mathematical functions defined in `.cpp` files, like: [`_XLgamma`](https://github.com/microsoft/STL/blob/e59dc201d19a57484d9e309e54ad66ef5055fff3/stl/inc/random#L82-L84).

## Wording

### What is changed and what is not

All deterministic algorithms and types in or depending on <random> should be constant evaluatable. This excludes `random_device` type and functions `rand()` and `srand()`.

This proposal also excludes iostream compatibility functions `operator<<` and `operator>>` as `iostream` types are not `constexpr` compatible yet (they will be in future proposal [P3758](https://wg21.link/P3758)).

### Header <algorithm> synopsis

:::wording

## Header <algorithm> synopsis [algorithm.syn]

namespace std {
// [alg.random.sample], sample
template<class PopulationIterator, class SampleIterator,
           class Distance, class UniformRandomBitGenerator>
constexpr SampleIterator sample(PopulationIterator first, PopulationIterator last,
                          SampleIterator out, Distance n,
                          UniformRandomBitGenerator&& g);

  namespace ranges {
template<input_iterator I, sentinel_for<I> S,
             weakly_incrementable O, class Gen>
requires (forward_iterator<I> || random_access_iterator<O>) &&
indirectly_copyable<I, O> &&
uniform_random_bit_generator<remove_reference_t<Gen>>
constexpr O sample(I first, S last, O out, iter_difference_t<I> n, Gen&& g);
    template<input_range R, weakly_incrementable O, class Gen>
requires (forward_range<R> || random_access_iterator<O>) &&
indirectly_copyable<iterator_t<R>, O> &&
uniform_random_bit_generator<remove_reference_t<Gen>>
constexpr O sample(R&& r, O out, range_difference_t<R> n, Gen&& g);
  }
// [alg.random.shuffle], shuffle
template<class RandomAccessIterator, class UniformRandomBitGenerator>
constexpr void shuffle(RandomAccessIterator first,
                 RandomAccessIterator last,
                 UniformRandomBitGenerator&& g);

  namespace ranges {
template<random_access_iterator I, sentinel_for<I> S, class Gen>
requires permutable<I> &&
uniform_random_bit_generator<remove_reference_t<Gen>>
constexpr I shuffle(I first, S last, Gen&& g);
    template<random_access_range R, class Gen>
requires permutable<iterator_t<R>> &&
uniform_random_bit_generator<remove_reference_t<Gen>>
constexpr borrowed_iterator_t<R> shuffle(R&& r, Gen&& g);
  }
}

:::

### Sample algorithm

:::wording

### Sample [alg.random.sample]

🔗

template<class PopulationIterator, class SampleIterator,
         class Distance, class UniformRandomBitGenerator>
constexpr SampleIterator sample(PopulationIterator first, PopulationIterator last,
                        SampleIterator out, Distance n,
                        UniformRandomBitGenerator&& g);

template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class Gen>
requires (forward_iterator<I> || random_access_iterator<O>) &&
indirectly_copyable<I, O> &&
uniform_random_bit_generator<remove_reference_t<Gen>>
constexpr O ranges::sample(I first, S last, O out, iter_difference_t<I> n, Gen&& g);
template<input_range R, weakly_incrementable O, class Gen>
requires (forward_range<R> || random_access_iterator<O>) &&
indirectly_copyable<iterator_t<R>, O> &&
uniform_random_bit_generator<remove_reference_t<Gen>>
constexpr O ranges::sample(R&& r, O out, range_difference_t<R> n, Gen&& g);

1

#

Mandates

: For the overload in namespace

std

,

Distance

is an integer type and

*first

is writable (

[iterator.requirements.general]

) to

out

.

2

#

Preconditions

:

out

is not in the range [

first, last

)

.

For the overload in namespace

std

:

- (2.1)PopulationIterator meets the *Cpp17InputIterator* requirements ([input.iterators]).
- (2.2)SampleIterator meets the *Cpp17OutputIterator* requirements ([output.iterators]).
- (2.3)SampleIterator meets the *Cpp17RandomAccessIterator* requirements ([random.access.iterators]) unless PopulationIterator models forward_iterator ([iterator.concept.forward]).
- (2.4)remove_reference_t<UniformRandomBitGenerator> meets the requirements of a uniform random bit generator type ([rand.req.urng]).

3

#

Effects

: Copies

min(last - first,  n)

elements (the

*sample*

)
from [

first, last

) (the

*population*

) to

out

such that each possible sample has equal probability of appearance

.

> [
> 
> Note 1
> 
> :
> 
> Algorithms that obtain such effects include
> 
> *selection sampling*
> 
> and
> 
> *reservoir sampling*
> 
> .
> 
> —
> 
> end note
> 
> ]

4

#

Returns

: The end of the resulting sample range

.

5

#

Complexity

:

O(last - first)

.

6

#

Remarks

:

- (6.1)For the overload in namespace std, stable if and only if PopulationIterator models forward_iterator. For the first overload in namespace ranges, stable if and only if I models forward_iterator.
- (6.2)To the extent that the implementation of this function makes use of random numbers, the object g serves as the implementation's source of randomness.

:::

### Shuffle algorithm

:::wording

### Shuffle [alg.random.shuffle]

🔗

template<class RandomAccessIterator, class UniformRandomBitGenerator>
constexpr void shuffle(RandomAccessIterator first,
               RandomAccessIterator last,
               UniformRandomBitGenerator&& g);

template<random_access_iterator I, sentinel_for<I> S, class Gen>
requires permutable<I> &&
uniform_random_bit_generator<remove_reference_t<Gen>>
constexpr I ranges::shuffle(I first, S last, Gen&& g);
template<random_access_range R, class Gen>
requires permutable<iterator_t<R>> &&
uniform_random_bit_generator<remove_reference_t<Gen>>
constexpr borrowed_iterator_t<R> ranges::shuffle(R&& r, Gen&& g);

1

#

Preconditions

: For the overload in namespace

std

:

- (1.1)RandomAccessIterator meets the *Cpp17ValueSwappable* requirements ([swappable.requirements]).
- (1.2)The type remove_reference_t<UniformRandomBitGenerator> meets the uniform random bit generator ([rand.req.urng]) requirements.

2

#

Effects

: Permutes the elements in the range [

first, last

)
such that each possible permutation of those elements
has equal probability of appearance

.

3

#

Returns

:

last

for the overloads in namespace

ranges

.

4

#

Complexity

: Exactly

(last - first) - 1

swaps

.

5

#

Remarks

: To the extent that the implementation of this function makes use
of random numbers, the object referenced by

g

shall serve as
the implementation's source of randomness

.

:::

### Distributions and generators

:::wording

## Random number generation [rand]

### General [rand.general]

1

#

Subclause [rand] defines a facility
for generating (pseudo-)random numbers

.

2

#

In addition to a few utilities,
four categories of entities are described:

*uniform random bit generators*

,

*random number engines*

,

*random number engine adaptors*

,
and

*random number distributions*

.

These categorizations are applicable
to types that meet the corresponding requirements,
to objects instantiated from such types,
and to templates producing such types when instantiated

.

> [
> 
> Note 1
> 
> :
> 
> These entities are specified in such a way
>  as to permit the binding
>  of any uniform random bit generator object
> 
> e
> 
> as the argument
>  to any random number distribution object
> 
> d
> 
> ,
>  thus producing a zero-argument function object
>  such as given by
> 
> bind(d,e)
> 
> .
> 
> —
> 
> end note
> 
> ]

3

#

Each of the entities specified in [rand]
has an associated arithmetic type (

[basic.fundamental]

)
identified as

result_type

.

With

T

as the

result_type

thus associated with such an entity,
that entity is characterized:

- (3.1)as *boolean* or equivalently as *boolean-valued*, if T is bool;
- (3.2)otherwise as *integral* or equivalently as *integer-valued*, if numeric_limits<T>::is_integer is true;
- (3.3)otherwise as *floating-point* or equivalently as *real-valued*.

If integer-valued,
an entity may optionally be further characterized as

*signed*

or

*unsigned*

,
according to

numeric_limits<T>​::​is_signed

.

4

#

Unless otherwise specified,
all descriptions of calculations
in [rand]
use mathematical real numbers

.

5

#

Throughout [rand],
the operators

bitand

,

bitor

, and

xor

denote the respective conventional bitwise operations

.

Further:

- (5.1)the operator rshift denotes a bitwise right shift with zero-valued bits appearing in the high bits of the result, and
- (5.2)the operator lshiftw denotes a bitwise left shift with zero-valued bits appearing in the low bits of the result, and whose result is always taken modulo 2w.

### Header <random> synopsis [rand.synopsis]

#include <initializer_list> // see [initializer.list.syn]
namespace std {
// [rand.req.urng], uniform random bit generator requirements
template<class G>
concept uniform_random_bit_generator = *see below*;           // freestanding
// [rand.eng.lcong], class template linear_congruential_engine
template<class UIntType, UIntType a, UIntType c, UIntType m>
class linear_congruential_engine;                           // partially freestanding
// [rand.eng.mers], class template mersenne_twister_engine
template<class UIntType, size_t w, size_t n, size_t m, size_t r,
           UIntType a, size_t u, UIntType d, size_t s,
           UIntType b, size_t t,
           UIntType c, size_t l, UIntType f>
class mersenne_twister_engine;

  // [rand.eng.sub], class template subtract_with_carry_engine
template<class UIntType, size_t w, size_t s, size_t r>
class subtract_with_carry_engine;                           // partially freestanding
// [rand.adapt.disc], class template discard_block_engine
template<class Engine, size_t p, size_t r>
class discard_block_engine;                                 // partially freestanding
// [rand.adapt.ibits], class template independent_bits_engine
template<class Engine, size_t w, class UIntType>
class independent_bits_engine;                              // partially freestanding
// [rand.adapt.shuf], class template shuffle_order_engine
template<class Engine, size_t k>
class shuffle_order_engine;

  // [rand.eng.philox], class template philox_engine
template<class UIntType, size_t w, size_t n, size_t r, UIntType... consts>
class philox_engine;

  // [rand.predef], engines and engine adaptors with predefined parameters
using minstd_rand0  = *see below*;      // freestanding
using minstd_rand   = *see below*;      // freestanding
using mt19937       = *see below*;      // freestanding
using mt19937_64    = *see below*;      // freestanding
using ranlux24_base = *see below*;      // freestanding
using ranlux48_base = *see below*;      // freestanding
using ranlux24      = *see below*;      // freestanding
using ranlux48      = *see below*;      // freestanding
using knuth_b       = *see below*;
  using philox4x32    = *see below*;
  using philox4x64    = *see below*;

  using default_random_engine = *see below*;

  // [rand.device], class random_device
class random_device;

  // [rand.util.seedseq], class seed_seq
class seed_seq;

  // [rand.util.canonical], function template generate_canonical
template<class RealType, size_t digits, class URBG>
constexpr RealType generate_canonical(URBG& g);

  namespace ranges {
// [alg.rand.generate], generate_random
template<class R, class G>
requires output_range<R, invoke_result_t<G&>> &&
uniform_random_bit_generator<remove_cvref_t<G>>
constexpr borrowed_iterator_t<R> generate_random(R&& r, G&& g);

    template<class G, output_iterator<invoke_result_t<G&>> O, sentinel_for<O> S>
requires uniform_random_bit_generator<remove_cvref_t<G>>
constexpr O generate_random(O first, S last, G&& g);

    template<class R, class G, class D>
requires output_range<R, invoke_result_t<D&, G&>> && invocable<D&, G&> &&
uniform_random_bit_generator<remove_cvref_t<G>> &&
               is_arithmetic_v<invoke_result_t<D&, G&>>
constexpr borrowed_iterator_t<R> generate_random(R&& r, G&& g, D&& d);

    template<class G, class D, output_iterator<invoke_result_t<D&, G&>> O, sentinel_for<O> S>
requires invocable<D&, G&> && uniform_random_bit_generator<remove_cvref_t<G>> &&
               is_arithmetic_v<invoke_result_t<D&, G&>>
constexpr O generate_random(O first, S last, G&& g, D&& d);
  }
// [rand.dist.uni.int], class template uniform_int_distribution
template<class IntType = int>
class uniform_int_distribution;                             // partially freestanding
// [rand.dist.uni.real], class template uniform_real_distribution
template<class RealType = double>
class uniform_real_distribution;

  // [rand.dist.bern.bernoulli], class bernoulli_distribution
class bernoulli_distribution;

  // [rand.dist.bern.bin], class template binomial_distribution
template<class IntType = int>
class binomial_distribution;

  // [rand.dist.bern.geo], class template geometric_distribution
template<class IntType = int>
class geometric_distribution;

  // [rand.dist.bern.negbin], class template negative_binomial_distribution
template<class IntType = int>
class negative_binomial_distribution;

  // [rand.dist.pois.poisson], class template poisson_distribution
template<class IntType = int>
class poisson_distribution;

  // [rand.dist.pois.exp], class template exponential_distribution
template<class RealType = double>
class exponential_distribution;

  // [rand.dist.pois.gamma], class template gamma_distribution
template<class RealType = double>
class gamma_distribution;

  // [rand.dist.pois.weibull], class template weibull_distribution
template<class RealType = double>
class weibull_distribution;

  // [rand.dist.pois.extreme], class template extreme_value_distribution
template<class RealType = double>
class extreme_value_distribution;

  // [rand.dist.norm.normal], class template normal_distribution
template<class RealType = double>
class normal_distribution;

  // [rand.dist.norm.lognormal], class template lognormal_distribution
template<class RealType = double>
class lognormal_distribution;

  // [rand.dist.norm.chisq], class template chi_squared_distribution
template<class RealType = double>
class chi_squared_distribution;

  // [rand.dist.norm.cauchy], class template cauchy_distribution
template<class RealType = double>
class cauchy_distribution;

  // [rand.dist.norm.f], class template fisher_f_distribution
template<class RealType = double>
class fisher_f_distribution;

  // [rand.dist.norm.t], class template student_t_distribution
template<class RealType = double>
class student_t_distribution;

  // [rand.dist.samp.discrete], class template discrete_distribution
template<class IntType = int>
class discrete_distribution;

  // [rand.dist.samp.pconst], class template piecewise_constant_distribution
template<class RealType = double>
class piecewise_constant_distribution;

  // [rand.dist.samp.plinear], class template piecewise_linear_distribution
template<class RealType = double>
class piecewise_linear_distribution;
}

### Requirements [rand.req]

#### General requirements [rand.req.genl]

1

#

Throughout [rand],
the effect of instantiating a template:

- (1.1)that has a template type parameter named Sseq is undefined unless the corresponding template argument is cv-unqualified and meets the requirements of seed sequence.
- (1.2)that has a template type parameter named URBG is undefined unless the corresponding template argument is cv-unqualified and meets the requirements of uniform random bit generator.
- (1.3)that has a template type parameter named Engine is undefined unless the corresponding template argument is cv-unqualified and meets the requirements of random number engine.
- (1.4)that has a template type parameter named RealType is undefined unless the corresponding template argument is cv-unqualified and is one of float, double, or long double.
- (1.5)that has a template type parameter named IntType is undefined unless the corresponding template argument is cv-unqualified and is one of short, int, long, long long, unsigned short, unsigned int, unsigned long, or unsigned long long.
- (1.6)that has a template type parameter named UIntType is undefined unless the corresponding template argument is cv-unqualified and is one of unsigned short, unsigned int, unsigned long, or unsigned long long.

2

#

Throughout [rand],
phrases of the form “

x

is an iterator of a specific kind”
shall be interpreted as equivalent to the more formal requirement that
“

x

is a value
of a type meeting the requirements
of the specified iterator type”

.

3

#

Throughout [rand],
any constructor that can be called with a single argument
and that meets a requirement specified in this subclause
shall be declared

explicit

.

#### Seed sequence requirements [rand.req.seedseq]

1

#

A

*seed sequence*

is an object
 that consumes a sequence
 of integer-valued data
 and produces a requested number
 of unsigned integer values

i

,

0≤i<232

,
 based on the consumed data

.

> [
> 
> Note 1
> 
> :
> 
> Such an object provides a mechanism
>  to avoid replication of streams of random variates
> 
> .
> 
> This can be useful, for example, in applications
>  requiring large numbers of random number engines
> 
> .
> 
> —
> 
> end note
> 
> ]

2

#

A class

S

meets the requirements
of a seed sequence
if the expressions shown
in Table

124

are valid and have the indicated semantics,
and if

S

also meets all other requirements
of

[rand.req.seedseq]

.

In Table

124

and throughout this subclause:

- (2.1)T is the type named by S's associated result_type;
- (2.2)q is a value of type S and r is a value of type S or const S;
- (2.3)ib and ie are input iterators with an unsigned integer value_type of at least 32 bits;
- (2.4)rb and re are mutable random access iterators with an unsigned integer value_type of at least 32 bits;
- (2.5)ob is an output iterator; and
- (2.6)il is a value of type initializer_list<T>.

Table

124

— Seed sequence requirements

[tab:rand.req.seedseq]

| 🔗**Expression** | Return type | Pre/post-condition | Complexity |
| --- | --- | --- | --- |
| 🔗S​::​result_type | T | T is an unsigned integer type of at least 32 bits. |  |
| 🔗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). | O(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. | O(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. | O(r.size()) |

#### Uniform random bit generator requirements [rand.req.urng]

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 1
> 
> :
> 
> 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)G::min() <= g(),
- (2.2)g() <= G::max(), and
- (2.3)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 (

[basic.fundamental]

),
and

G

provides a nested

*typedef-name*

result_type

that denotes the same type as

invoke_result_t<G&>

.

#### Random number engine requirements [rand.req.eng]

1

#

A

*random number engine*

(commonly shortened to

*engine*

)

e

of type

E

is a uniform random bit generator
that additionally meets the requirements
(e.g., for seeding and for input/output)
specified in this subclause

.

2

#

At any given time,

e

has a state

e

i

for some integer

i  ≥ 0

.

Upon construction,

e

has an initial state

e

0

.

An engine's state may be established via
 a constructor,
 a

seed

function,
 assignment,
 or a suitable

operator>>

.

3

#

E

's specification shall define:

- (3.1)the size of E's state in multiples of the size of result_type, given as an integral constant expression;
- (3.2)the *transition algorithm* TA by which e's state ei is advanced to its *successor state* ei+1; and
- (3.3)the *generation algorithm* GA by which an engine's state is mapped to a value of type result_type.

4

#

A class

E

that meets the requirements
of a

uniform random bit generator

also meets the requirements
of a

*random number engine*

if the expressions shown
in Table

125

are valid and have the indicated semantics,
and if

E

also meets all other requirements
of

[rand.req.eng]

.

In Table

125

and throughout this subclause:

- (4.1)T is the type named by E's associated result_type;
- (4.2)e is a value of E, v is an lvalue of E, x and y are (possibly const) values of E;
- (4.3)s is a value of T;
- (4.4)q is an lvalue meeting the requirements of a seed sequence;
- (4.5)z is a value of type unsigned long long;
- (4.6)os is an lvalue of the type of some class template specialization basic_ostream<charT, traits>; and
- (4.7)is is an lvalue of the type of some class template specialization basic_istream<charT, traits>;

where

charT

and

traits

are constrained
according to

[strings]

and

[input.output]

.

Table

125

— Random number engine requirements

[tab:rand.req.eng]

| 🔗**Expression** | Return type | Pre/post-condition | Complexity |
| --- | --- | --- | --- |
| 🔗E() |  | Creates an engine with the same initial state as all other default-constructed engines of type E. | O(size of state) |
| 🔗E(x) |  | Creates an engine that compares equal to x. | O(size of state) |
| 🔗E(s) |  | Creates an engine with initial state determined by s. | O(size of state) |
| 🔗E(q)241 |  | Creates an engine with an initial state that depends on a sequence produced by one call to q.generate. | same as complexity of q.generate called on a sequence whose length is size of state |
| 🔗e.seed() | void | *Postconditions*: e == E(). | same as E() |
| 🔗e.seed(s) | void | *Postconditions*: e == E(s). | same as E(s) |
| 🔗e.seed(q) | void | *Postconditions*: e == E(q). | same as E(q) |
| 🔗e() | T | Advances e's state ei to ei+1 =TA(ei) and returns GA(ei). | per [rand.req.urng] |
| 🔗e.discard(z)242 | void | Advances e's state ei to ei+z by any means equivalent to z consecutive calls e(). | no worse than the complexity of z consecutive calls e() |
| 🔗x == y | bool | This operator is an equivalence relation. With Sx and Sy as the infinite sequences of values that would be generated by repeated future calls to x() and y(), respectively, returns true if Sx=Sy; else returns false. | O(size of state) |
| 🔗x != y | bool | !(x == y). | O(size of state) |

5

#

E

shall meet the

*Cpp17CopyConstructible*

(Table

32

)
and

*Cpp17CopyAssignable*

(Table

34

) requirements

.

These operations shall each be of complexity
no worse than

O(size of state)

.

6

#

On hosted implementations,
the following expressions are well-formed and have the specified semantics

.

🔗

os << x

7

#

Effects

: With

os.*fmtflags*

set to

ios_base​::​dec|ios_base​::​left

and the fill character set to the space character,
writes to

os

the textual representation
of

x

's current state

.

In the output,
adjacent numbers are separated
by one or more space characters

.

8

#

Postconditions

: The

os.*fmtflags*

and fill character are unchanged

.

9

#

Result

: reference to the type of

os

.

10

#

Returns

:

os

.

11

#

Complexity

:

O(size of state)

🔗

is >> v

12

#

Preconditions

:

is

provides a textual representation
that was previously written
using an output stream
whose imbued locale
was the same as that of

is

,
and whose type's template specialization arguments

charT

and

traits

were respectively the same as those of

is

.

13

#

Effects

: With

is.*fmtflags*

set to

ios_base​::​dec

,
sets

v

's state
as determined by reading its textual representation from

is

.

If bad input is encountered,
ensures that

v

's state is unchanged by the operation
and
calls

is.setstate(ios_base​::​failbit)

(which may throw

ios_base​::​failure

(

[iostate.flags]

))

.

If a textual representation written via

os << x

was subsequently read via

is >> v

,
then

x == v

provided that there have been no intervening invocations
of

x

or of

v

.

14

#

Postconditions

: The

is.*fmtflags*

are unchanged

.

15

#

Result

: reference to the type of

is

.

16

#

Returns

:

is

.

17

#

Complexity

:

O(size of state)

241)

This constructor
  (as well as the subsequent corresponding

seed()

function)
  can be particularly useful
  to applications requiring
  a large number of independent random sequences

.

242)

This operation is common
  in user code,
  and can often be implemented
  in an engine-specific manner
  so as to provide significant performance improvements
  over an equivalent naive loop
  that makes

z

consecutive calls

e()

.

#### Random number engine adaptor requirements [rand.req.adapt]

1

#

A

*random number engine adaptor*

(commonly shortened to

*adaptor*

)

a

of type

A

is a random number engine
that takes values
produced by some other random number engine,
and applies an algorithm to those values
in order to deliver a sequence of values
with different randomness properties

.

An engine

b

of type

B

adapted in this way
is termed a

*base engine*

in this context

.

The expression

a.base()

shall be valid and shall return a
const reference to

a

's base engine

.

2

#

The requirements of a random number engine type
shall be interpreted as follows
with respect to a random number engine adaptor type

.

🔗

A::A();

3

#

Effects

: The base engine is initialized
 as if by its default constructor

.

🔗

bool operator==(const A& a1, const A& a2);

4

#

Returns

:

true

if

a1

's base engine is equal to

a2

's base engine

.

Otherwise returns

false

.

🔗

A::A(result_type s);

5

#

Effects

: The base engine is initialized
 with

s

.

🔗

template<class Sseq> A::A(Sseq& q);

6

#

Effects

: The base engine is initialized
 with

q

.

🔗

void seed();

7

#

Effects

: With

b

as the base engine, invokes

b.seed()

.

🔗

void seed(result_type s);

8

#

Effects

: With

b

as the base engine, invokes

b.seed(s)

.

🔗

template<class Sseq> void seed(Sseq& q);

9

#

Effects

: With

b

as the base engine, invokes

b.seed(q)

.

10

#

A

shall also meet
the following additional requirements:

- (10.1)The complexity of each function shall not exceed the complexity of the corresponding function applied to the base engine.
- (10.2)The state of A shall include the state of its base engine. The size of A's state shall be no less than the size of the base engine.
- (10.3)Copying A's state (e.g., during copy construction or copy assignment) shall include copying the state of the base engine of A.
- (10.4)The textual representation of A shall include the textual representation of its base engine.

#### Random number distribution requirements [rand.req.dist]

1

#

A

*random number distribution*

(commonly shortened to

*distribution*

)

d

of type

D

is a function object
returning values
that are distributed according to
an associated mathematical

*probability density function*

p(z)

or according to
an associated

*discrete probability function*

P(zi)

.

A distribution's specification
identifies its associated probability function

p(z)

or

P(zi)

.

2

#

An associated probability function is typically expressed
using certain externally-supplied quantities
known as the

*parameters of the distribution*

.

Such distribution parameters are identified
in this context by writing, for example,

p(z | a,b)

or

P(zi|a,b)

,
  to name specific parameters,
or by writing, for example,

p(z |{p})

or

P(zi|{p})

,
  to denote a distribution's parameters

p

taken as a whole

.

3

#

A class

D

meets the requirements
of a

*random number distribution*

if the expressions shown
in Table

126

are valid and have the indicated semantics,
and if

D

and its associated types
also meet all other requirements
of

[rand.req.dist]

.

In Table

126

and throughout this subclause,

- (3.1)T is the type named by D's associated result_type;
- (3.2)P is the type named by D's associated param_type;
- (3.3)d is a value of D, and x and y are (possibly const) values of D;
- (3.4)glb and lub are values of T respectively corresponding to the greatest lower bound and the least upper bound on the values potentially returned by d's operator(), as determined by the current values of d's parameters;
- (3.5)p is a (possibly const) value of P;
- (3.6)g, g1, and g2 are lvalues of a type meeting the requirements of a uniform random bit generator;
- (3.7)os is an lvalue of the type of some class template specialization basic_ostream<charT, traits>; and
- (3.8)is is an lvalue of the type of some class template specialization basic_istream<charT, traits>;

where

charT

and

traits

are constrained
according to

[strings]

and

[input.output]

.

Table

126

— Random number distribution requirements

[tab:rand.req.dist]

| 🔗**Expression** | Return type | Pre/post-condition | Complexity |
| --- | --- | --- | --- |
| 🔗D​::​result_type | T | T is an arithmetic type. |  |
| 🔗D​::​param_type | P |  |  |
| 🔗D() |  | Creates a distribution whose behavior is indistinguishable from that of any other newly default-constructed distribution of type D. | constant |
| 🔗D(p) |  | Creates a distribution whose behavior is indistinguishable from that of a distribution newly constructed directly from the values used to construct p. | same as p's construction |
| 🔗d.reset() | void | Subsequent uses of d do not depend on values produced by any engine prior to invoking reset. | constant |
| 🔗x.param() | P | Returns a value p such that D(p).param() == p. | no worse than the complexity of D(p) |
| 🔗d.param(p) | void | *Postconditions*: d.param() == p. | no worse than the complexity of D(p) |
| 🔗d(g) | T | With p=d.param(), the sequence of numbers returned by successive invocations with the same object g is randomly distributed according to the associated p(z \|{p}) or P(zi\|{p}) function. | amortized constant number of invocations of g |
| 🔗d(g,p) | T | The sequence of numbers returned by successive invocations with the same objects g and p is randomly distributed according to the associated p(z \|{p}) or P(zi\|{p}) function. | amortized constant number of invocations of g |
| 🔗x.min() | T | Returns glb. | constant |
| 🔗x.max() | T | Returns lub. | constant |
| 🔗x == y | bool | This operator is an equivalence relation. Returns true if x.param() == y.param() and S1=S2, where S1 and S2 are the infinite sequences of values that would be generated, respectively, by repeated future calls to x(g1) and y(g2) whenever g1 == g2. Otherwise returns false. | constant |
| 🔗x != y | bool | !(x == y). | same as x == y. |

4

#

D

shall meet the

*Cpp17CopyConstructible*

(Table

32

)
and

*Cpp17CopyAssignable*

(Table

34

) requirements

.

5

#

The sequence of numbers
produced by repeated invocations of

d(g)

shall be independent of any invocation of

os << d

or of
any

const

member function of

D

between any of the invocations of

d(g)

.

6

#

If a textual representation is written using

os << x

and that representation is restored
into the same or a different object

y

of the same type using

is >> y

,
repeated invocations of

y(g)

shall produce the same sequence of numbers
as would repeated invocations of

x(g)

.

7

#

It is unspecified whether

D​::​param_type

is declared as a (nested)

class

or via a

typedef

.

In [rand],
declarations of

D​::​param_type

are in the form of

typedef

s
for convenience of exposition only

.

8

#

P

shall meet the

*Cpp17CopyConstructible*

(Table

32

),

*Cpp17CopyAssignable*

(Table

34

),
and

*Cpp17EqualityComparable*

(Table

28

) requirements

.

9

#

For each of the constructors of

D

taking arguments corresponding to parameters of the distribution,

P

shall have a corresponding constructor
subject to the same requirements
and taking arguments identical in number, type, and default values

.

Moreover,
for each of the member functions of

D

that return values corresponding to parameters of the distribution,

P

shall have a corresponding member function
with the identical name, type, and semantics

.

10

#

P

shall have a declaration of the form

using distribution_type =  D;

11

#

On hosted implementations,
the following expressions are well-formed and have the specified semantics

.

🔗

os << x

12

#

Effects

: Writes to

os

a textual representation
for the parameters and the additional internal data of

x

.

13

#

Postconditions

: The

os.*fmtflags*

and fill character are unchanged

.

14

#

Result

: reference to the type of

os

.

15

#

Returns

:

os

.

🔗

is >> d

16

#

Preconditions

:

is

provides a textual representation
that was previously written
using an

os

whose imbued locale
and whose type's template specialization arguments

charT

and

traits

were the same as those of

is

.

17

#

Effects

: Restores from

is

the parameters and additional internal data of the lvalue

d

.

If bad input is encountered,
ensures that

d

is unchanged by the operation
and
calls

is.setstate(ios_base​::​failbit)

(which may throw

ios_base​::​failure

(

[iostate.flags]

))

.

18

#

Postconditions

: The

is.*fmtflags*

are unchanged

.

19

#

Result

: reference to the type of

is

.

20

#

Returns

:

is

.

### Random number engine class templates [rand.eng]

#### General [rand.eng.general]

1

#

Each type instantiated
from a class template specified in

[rand.eng]

meets the requirements
of a

random number engine

type

.

2

#

Except where specified otherwise,
the complexity of each function
specified in

[rand.eng]

is constant

.

3

#

Except where specified otherwise,
no function described in

[rand.eng]

throws an exception

.

4

#

Every function described in

[rand.eng]

that has a function parameter

q

of type

Sseq&

for a template type parameter named

Sseq

that is different from type

seed_seq

throws what and when the invocation of

q.generate

throws

.

5

#

Descriptions are provided in

[rand.eng]

only for engine operations
that are not described in

[rand.req.eng]

or for operations where there is additional semantic information

.

In particular,
declarations for copy constructors,
for copy assignment operators,
for streaming operators,
and for equality and inequality operators
are not shown in the synopses

.

6

#

Each template specified in

[rand.eng]

requires one or more relationships,
involving the value(s) of its constant template parameter(s), to hold

.

A program instantiating any of these templates
is ill-formed
if any such required relationship fails to hold

.

7

#

For every random number engine and for every random number engine adaptor

X

defined in

[rand.eng]

and in

[rand.adapt]

:

- (7.1)if the constructor template<class Sseq> explicit X(Sseq& q); is called with a type Sseq that does not qualify as a seed sequence, then this constructor shall not participate in overload resolution;
- (7.2)if the member function template<class Sseq> void seed(Sseq& q); is called with a type Sseq that does not qualify as a seed sequence, then this function shall not participate in overload resolution.

The extent to which an implementation determines that a type cannot be a seed sequence
is unspecified, except that as a minimum a type shall not qualify as a seed sequence
if it is implicitly convertible to

X​::​result_type

.

#### Class template linear_congruential_engine [rand.eng.lcong]

1

#

A

linear_congruential_engine

random number engine
produces unsigned integer random numbers

.

The state

x

i

of a

linear_congruential_engine

object

x

is of size

1

and consists of a single integer

.

The transition algorithm
is a modular linear function of the form

TA(xi)=(a⋅xi+c)modm

;
the generation algorithm
is

GA(xi)=xi+1

.

🔗namespace std {
template<class UIntType, UIntType a, UIntType c, UIntType m>
class linear_congruential_engine {
public:
// types
using result_type = UIntType;

    // engine characteristics
static constexpr result_type multiplier = a;
    static constexpr result_type increment = c;
    static constexpr result_type modulus = m;
    static constexpr result_type min() { return c == 0u ? 1u: 0u; }
static constexpr result_type max() { return m - 1u; }
static constexpr result_type default_seed = 1u;

    // constructors and seeding functions
constexpr linear_congruential_engine() : linear_congruential_engine(default_seed) {}
constexpr explicit linear_congruential_engine(result_type s);
    template<class Sseq> constexpr explicit linear_congruential_engine(Sseq& q);
    constexpr void seed(result_type s = default_seed);
    template<class Sseq> constexpr void seed(Sseq& q);

    // equality operators
constexpr friend bool operator==(const linear_congruential_engine& x,
                           const linear_congruential_engine& y);

    // generating functions
constexpr result_type operator()();
    constexpr void discard(unsigned long long z);

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os,            // hosted
const linear_congruential_engine& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is,            // hosted
                   linear_congruential_engine& x);
  };
}

2

#

If the template parameter

m

is

0

,
the modulus

m

used throughout

[rand.eng.lcong]

is

numeric_limits<result_type>​::​max()

plus

1

.

> [
> 
> Note 1
> 
> :
> 
> m
> 
> need not be representable
>  as a value of type
> 
> result_type
> 
> .
> 
> —
> 
> end note
> 
> ]

3

#

If the template parameter

m

is not

0

,
the following relations shall hold:

a < m

and

c < m

.

4

#

The textual representation
consists of
the value of

x

i

.

🔗

constexpr explicit linear_congruential_engine(result_type s);

5

#

Effects

: If

cmodm

is

0

and

smodm

is

0

,
 sets the engine's state to

1

,
 otherwise sets the engine's state to

smodm

.

🔗

template<class Sseq> constexpr explicit linear_congruential_engine(Sseq& q);

6

#

Effects

: With

k=⌈log2m32⌉

and

a

an array (or equivalent)
 of length

k+3

,
 invokes

q.generate(a+0, a+k+3)

and then computes

S=(∑k−1j=0aj+3⋅232j)modm

.

If

cmodm

is

0

and

S

is

0

,
 sets the engine's state to

1

,
 else sets the engine's state
 to

S

.

#### Class template mersenne_twister_engine [rand.eng.mers]

1

#

A

mersenne_twister_engine

random number
engine

243

produces unsigned integer random numbers
in the closed interval

[0,2w−1]

.

The
state

x

i

of a

mersenne_twister_engine

object

x

is of size

n

and consists of a sequence

X

of

n

values of the type delivered by

x

;
all subscripts applied to

X

are to be taken modulo

n

.

2

#

The transition algorithm
employs a twisted generalized feedback shift register
defined by shift values

n

and

m

, a twist value

r

,
and a conditional xor-mask

a

.

To improve the uniformity of the result,
the bits of the raw shift register are additionally

*tempered*

(i.e., scrambled) according to a bit-scrambling matrix
defined by values

u

,

d

,

s

,

b

,

t

,

c

, and

ℓ

.

The state transition is performed as follows:

- (2.1)Concatenate the upper w−r bits of Xi−n with the lower r bits of Xi+1−n to obtain an unsigned integer value Y.
- (2.2)With α=a⋅(Ybitand1), set Xi to Xi+m−nxor(Yrshift1)xorα.

The sequence

X

is initialized
with the help of an initialization multiplier

f

.

3

#

The generation algorithm
 determines the unsigned integer values

z1,z2,z3,z4

as follows,
 then delivers

z4

as its result:

- (3.1)Let z1=Xixor((Xirshiftu)bitandd).
- (3.2)Let z2=z1xor((z1lshiftws)bitandb).
- (3.3)Let z3=z2xor((z2lshiftwt)bitandc).
- (3.4)Let z4=z3xor(z3rshiftℓ).

🔗namespace std {
template<class UIntType, size_t w, size_t n, size_t m, size_t r,
           UIntType a, size_t u, UIntType d, size_t s,
           UIntType b, size_t t,
           UIntType c, size_t l, UIntType f>
class mersenne_twister_engine {
public:
// types
using result_type = UIntType;

    // engine characteristics
static constexpr size_t word_size = w;
    static constexpr size_t state_size = n;
    static constexpr size_t shift_size = m;
    static constexpr size_t mask_bits = r;
    static constexpr UIntType xor_mask = a;
    static constexpr size_t tempering_u = u;
    static constexpr UIntType tempering_d = d;
    static constexpr size_t tempering_s = s;
    static constexpr UIntType tempering_b = b;
    static constexpr size_t tempering_t = t;
    static constexpr UIntType tempering_c = c;
    static constexpr size_t tempering_l = l;
    static constexpr UIntType initialization_multiplier = f;
    static constexpr result_type min() { return 0; }
static constexpr result_type max() { return 2w−1; }
static constexpr result_type default_seed = 5489u;

    // constructors and seeding functions
constexpr mersenne_twister_engine() : mersenne_twister_engine(default_seed) {}
constexpr explicit mersenne_twister_engine(result_type value);
    template<class Sseq> constexpr explicit mersenne_twister_engine(Sseq& q);
    constexpr void seed(result_type value = default_seed);
    template<class Sseq> constexpr void seed(Sseq& q);

    // equality operators
constexpr friend bool operator==(const mersenne_twister_engine& x, const mersenne_twister_engine& y);

    // generating functions
constexpr result_type operator()();
    constexpr void discard(unsigned long long z);

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os,            // hosted
const mersenne_twister_engine& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is,            // hosted
                   mersenne_twister_engine& x);
  };
}

4

#

The following relations shall hold:

0 < m

,

m <= n

,

2u < w

,

r <= w

,

u <= w

,

s <= w

,

t <= w

,

l <= w

,

w <= numeric_limits<UIntType>​::​digits

,

a <= (1u << w) - 1u

,

b <= (1u << w) - 1u

,

c <= (1u << w) - 1u

,

d <= (1u << w) - 1u

,
and

f <= (1u << w) - 1u

.

5

#

The textual representation
of

x

i

consists of the values of

Xi−n,…,Xi−1

,
in that order

.

🔗

constexpr explicit mersenne_twister_engine(result_type value);

6

#

Effects

: Sets

X−n

to

valuemod2w

.

Then, iteratively for

i=1−n,…,−1

, sets

Xi

to

[f⋅(Xi−1xor(Xi−1rshift(w−2)))+imodn]mod2w.

7

#

Complexity

:

O(n)

.

🔗

template<class Sseq> constexpr explicit mersenne_twister_engine(Sseq& q);

8

#

Effects

: With

k=⌈w/32⌉

and

a

an array (or equivalent)
 of length

n⋅k

,
 invokes

q.generate(a+0, a+n⋅k)

and then, iteratively for

i=−n,…,−1

,
 sets

Xi

to

(∑k−1j=0ak(i+n)+j⋅232j)mod2w

.

Finally,
 if the most significant

w−r

bits of

X−n

are zero,
 and if each of the other resulting

Xi

is

0

,
 changes

X−n

to

2w−1

.

243)

The name of this engine refers, in part, to a property of its period:
 For properly-selected values of the parameters,
 the period is closely related to a large Mersenne prime number

.

#### Class template subtract_with_carry_engine [rand.eng.sub]

1

#

A

subtract_with_carry_engine

random number engine
produces unsigned integer random numbers

.

2

#

The state

x

i

of a

subtract_with_carry_engine

object

x

is of size

O(r)

,
and consists of
a sequence

X

of

r

integer values

0≤Xi<m=2w

;
all subscripts applied to

X

are to be taken modulo

r

.

The state

x

i

additionally consists of an integer

c

(known as the

*carry*

)
whose value is either

0

or

1

.

3

#

The state transition
is performed as follows:

- (3.1)Let Y=Xi−s−Xi−r−c.
- (3.2)Set Xi to y=Ymodm. Set c to 1 if Y<0, otherwise set c to 0.

> [
> 
> Note 1
> 
> :
> 
> This algorithm corresponds
>  to a modular linear function
>  of the form
> 
> TA(xi)=(a⋅xi)modb
> 
> ,
>  where
> 
> b
> 
> is of the form
> 
> mr−ms+1
> 
> and
> 
> a=b−(b−1)/m
> 
> .
> 
> —
> 
> end note
> 
> ]

4

#

The generation algorithm
is given by

GA(xi)=y

,
where

y

is the value produced as a result
of advancing the engine's state as described above

.

🔗namespace std {
template<class UIntType, size_t w, size_t s, size_t r>
class subtract_with_carry_engine {
public:
// types
using result_type = UIntType;

    // engine characteristics
static constexpr size_t word_size = w;
    static constexpr size_t short_lag = s;
    static constexpr size_t long_lag = r;
    static constexpr result_type min() { return 0; }
static constexpr result_type max() { return m−1; }
static constexpr uint_least32_t default_seed = 19780503u;

    // constructors and seeding functions
constexpr subtract_with_carry_engine() : subtract_with_carry_engine(0u) {}
constexpr explicit subtract_with_carry_engine(result_type value);
    template<class Sseq> constexpr explicit subtract_with_carry_engine(Sseq& q);
    constexpr void seed(result_type value = 0u);
    template<class Sseq> constexpr void seed(Sseq& q);

    // equality operators
constexpr friend bool operator==(const subtract_with_carry_engine& x,
                           const subtract_with_carry_engine& y);

    // generating functions
constexpr result_type operator()();
    constexpr void discard(unsigned long long z);

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os,            // hosted
const subtract_with_carry_engine& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is,            // hosted
                   subtract_with_carry_engine& x);
  };
}

5

#

The following relations shall hold:

0u < s

,

s < r

,

0 < w

,
and

w <= numeric_limits<UIntType>​::​digits

.

6

#

The textual representation
consists of the values of

Xi−r,…,Xi−1

,
in that order, followed by

c

.

🔗

constexpr explicit subtract_with_carry_engine(result_type value);

7

#

Effects

: Sets the values of

X−r,…,X−1

,
 in that order, as specified below

.

If

X−1

is then

0

,
 sets

c

to

1

;
 otherwise sets

c

to

0

.

To set the values

Xk

,
 first construct

e

, a

linear_congruential_engine

object,
 as if by the following definition:

linear_congruential_engine<uint_least32_t, 40014u, 0u, 2147483563u> e(
  value == 0u ? default_seed : static_cast<uint_least32_t>(value % 2147483563u));

Then, to set each

Xk

,
 obtain new values

z0,…,zn−1

from

n=⌈w/32⌉

successive invocations
 of

e

.

Set

Xk

to

(∑n−1j=0zj⋅232j)modm

.

8

#

Complexity

: Exactly

n⋅r

invocations
 of

e

.

🔗

template<class Sseq> constexpr explicit subtract_with_carry_engine(Sseq& q);

9

#

Effects

: With

k=⌈w/32⌉

and

a

an array (or equivalent)
 of length

r⋅k

,
 invokes

q.generate(a+0, a+r⋅k)

and then, iteratively for

i=−r,…,−1

,
 sets

Xi

to

(∑k−1j=0ak(i+r)+j⋅232j)modm

.

If

X−1

is then

0

,
 sets

c

to

1

;
 otherwise sets

c

to

0

.

#### Class template philox_engine [rand.eng.philox]

1

#

A

philox_engine

random number engine produces
unsigned integer random numbers in the interval [

0, m

),
where

m=2w

and
the template parameter

w

defines the range of the produced numbers

.

The state of a

philox_engine

object consists of
a sequence

X

of

n

unsigned integer values of width

w

,
a sequence

K

of

n/2

values of

result_type

,
a sequence

Y

of

n

values of

result_type

, and
a scalar

i

, where

- (1.1)X is the interpretation of the unsigned integer *counter* value Z:=∑n−1j=0Xj⋅2wj of n⋅w bits,
- (1.2)K are keys, which are generated once from the seed (see constructors below) and remain constant unless the seed function ([rand.req.eng]) is invoked,
- (1.3)Y stores a batch of output values, and
- (1.4)i is an index for an element of the sequence Y.

2

#

The generation algorithm returns

Yi

,
the value stored in the

ith

element of

Y

after applying
the transition algorithm

.

3

#

The state transition is performed as if by the following algorithm:

i = i + 1
if (i == n) {
Y = Philox(K, X) // *see below*
Z = Z + 1
i = 0
}

4

#

The

Philox

function maps the length-

n/2

sequence

K

and
the length-

n

sequence

X

into a length-

n

output sequence

Y

.

Philox applies an

r

-round substitution-permutation network to the values in

X

.

A single round of the generation algorithm performs the following steps:

- (4.1)The output sequence X′ of the previous round (X in case of the first round) is permuted to obtain the intermediate state V: Vj=X′fn(j) where j=0,…,n−1 and fn(j) is defined in Table 127. Table 127 — Values for the word permutation fn(j) [tab:rand.eng.philox.f] 🔗 f n (j) j 🔗 0 1 2 3 🔗 n 2 0 1 🔗 4 2 1 0 3 🔗 [*Note 1*: For n=2 the sequence is not permuted. — *end note*]
- (4.2)The following computations are applied to the elements of the V sequence: X2k+0=mulhi(V2k,Mk,w)xorkeyqkxorV2k+1 X2k+1=mullo(V2k,Mk,w) where:
  - (4.2.1)mullo(a, b, w) is the low half of the modular multiplication of a and b: (a⋅b)mod2w,
  - (4.2.2)mulhi(a, b, w) is the high half of the modular multiplication of a and b: (⌊(a⋅b)/2w⌋),
  - (4.2.3)k=0,…,n/2−1 is the index in the sequences,
  - (4.2.4)q=0,…,r−1 is the index of the round,
  - (4.2.5)keyqk is the kth round key for round q, keyqk:=(Kk+q⋅Ck)mod2w,
  - (4.2.6)Kk are the elements of the key sequence K,
  - (4.2.7)Mk is multipliers[k], and
  - (4.2.8)Ck is round_consts[k].

5

#

After

r

applications of the single-round function,

Philox

returns the sequence

Y=X′

.

🔗namespace std {
template<class UIntType, size_t w, size_t n, size_t r, UIntType... consts>
class philox_engine {
static constexpr size_t *array-size* = n / 2;   // *exposition only*
public:
// types
using result_type = UIntType;

    // engine characteristics
static constexpr size_t word_size = w;
    static constexpr size_t word_count = n;
    static constexpr size_t round_count = r;
    static constexpr array<result_type, *array-size*> multipliers;
    static constexpr array<result_type, *array-size>* round_consts;
    static constexpr result_type min() { return 0; }
static constexpr result_type max() { return m - 1; }
static constexpr result_type default_seed = 20111115u;

    // constructors and seeding functions
constexpr philox_engine() : philox_engine(default_seed) {}
constexpr explicit philox_engine(result_type value);
    template<class Sseq> constexpr explicit philox_engine(Sseq& q);
    constexpr void seed(result_type value = default_seed);
    template<class Sseq> constexpr void seed(Sseq& q);

    constexpr void set_counter(const array<result_type, n>& counter);

    // equality operators
constexpr friend bool operator==(const philox_engine& x, const philox_engine& y);

    // generating functions
constexpr result_type operator()();
    constexpr void discard(unsigned long long z);

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const philox_engine& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, philox_engine& x);
  };
}

6

#

Mandates

:

- (6.1)sizeof...(consts) == n is true, and
- (6.2)n == 2 || n == 4 is true, and
- (6.3)0 < r is true, and
- (6.4)0 < w && w <= numeric_limits<UIntType>::digits is true.

7

#

The template parameter pack

consts

represents
the

Mk

and

Ck

constants which are grouped as follows:

[M0,C0,M1,C1,M2,C2,…,Mn/2−1,Cn/2−1]

.

8

#

The textual representation consists of the values of

K0,…,Kn/2−1,X0,…,Xn−1,i

, in that order

.

> [
> 
> Note 2
> 
> :
> 
> The stream extraction operator can reconstruct
> 
> Y
> 
> from
> 
> K
> 
> and
> 
> X
> 
> , as needed
> 
> .
> 
> —
> 
> end note
> 
> ]

🔗

constexpr explicit philox_engine(result_type value);

9

#

Effects

: Sets the

K0

element of sequence

K

to

valuemod2w

.

All elements of sequences

X

and

K

(except

K0

) are set to

0

.

The value of

i

is set to

n−1

.

🔗

template<class Sseq> constexpr explicit philox_engine(Sseq& q);

10

#

Effects

: With

p=⌈w/32⌉

and
an array (or equivalent)

a

of length

(n/2)⋅p

,
invokes

q.generate(a + 0, a + n / 2 * p)

and
then iteratively for

k=0,…,n/2−1

,
sets

Kk

to

(∑p−1j=0akp+j⋅232j)mod2w

.

All elements of sequence

X

are set to

0

.

The value of

i

is set to

n−1

.

🔗

constexpr void set_counter(const array<result_type, n>& c);

11

#

Effects

: For

j=0,…,n−1

sets

Xj

to

Cn−1−jmod2w

.

The value of

i

is set to

n−1

.

> [
> 
> Note 3
> 
> :
> 
> The counter is the value
> 
> Z
> 
> introduced at the beginning of this subclause
> 
> .
> 
> —
> 
> end note
> 
> ]

### Random number engine adaptor class templates [rand.adapt]

#### General [rand.adapt.general]

1

#

Each type instantiated
from a class template specified in

[rand.adapt]

meets the requirements
of a

random number engine adaptor

type

.

2

#

Except where specified otherwise,
the complexity of each function
specified in

[rand.adapt]

is constant

.

3

#

Except where specified otherwise,
no function described in

[rand.adapt]

throws an exception

.

4

#

Every function described in

[rand.adapt]

that has a function parameter

q

of type

Sseq&

for a template type parameter named

Sseq

that is different from type

seed_seq

throws what and when the invocation of

q.generate

throws

.

5

#

Descriptions are provided in

[rand.adapt]

only for adaptor operations
that are not described in subclause

[rand.req.adapt]

or for operations where there is additional semantic information

.

In particular,
declarations for copy constructors,
for copy assignment operators,
for streaming operators,
and for equality and inequality operators
are not shown in the synopses

.

6

#

Each template specified in

[rand.adapt]

requires one or more relationships,
involving the value(s) of its constant template parameter(s), to hold

.

A program instantiating any of these templates
is ill-formed
if any such required relationship fails to hold

.

#### Class template discard_block_engine [rand.adapt.disc]

1

#

A

discard_block_engine

random number engine adaptor
produces random numbers
selected from those produced by some base engine

e

.

The state

x

i

of a

discard_block_engine

engine adaptor object

x

consists of the state

e

i

of its base engine

e

and an additional integer

n

.

The size of the state is
 the size of

e

's state plus

1

.

2

#

The transition algorithm
discards all but

r>0

values
from each block of

p  ≥ r

values delivered by

e

.

The state transition is performed as follows:
If

n  ≥ r

,
 advance the state of

e

from

e

i

to

e

i+p−r

and set

n

to

0

.

In any case,
 then increment

n

and advance

e

's then-current state

e

j

to

e

j+1

.

3

#

The generation algorithm
yields the value returned by the last invocation of

e()

while advancing

e

's state as described above

.

🔗namespace std {
template<class Engine, size_t p, size_t r>
class discard_block_engine {
public:
// types
using result_type = typename Engine::result_type;

    // engine characteristics
static constexpr size_t block_size = p;
    static constexpr size_t used_block = r;
    static constexpr result_type min() { return Engine::min(); }
static constexpr result_type max() { return Engine::max(); }
// constructors and seeding functions
constexpr discard_block_engine();
    constexpr explicit discard_block_engine(const Engine& e);
    constexpr explicit discard_block_engine(Engine&& e);
    constexpr explicit discard_block_engine(result_type s);
    template<class Sseq> constexpr explicit discard_block_engine(Sseq& q);
    constexpr void seed();
    constexpr void seed(result_type s);
    template<class Sseq> constexpr void seed(Sseq& q);

    // equality operators
constexpr friend bool operator==(const discard_block_engine& x, const discard_block_engine& y);

    // generating functions
constexpr result_type operator()();
    constexpr void discard(unsigned long long z);

    // property functions
constexpr const Engine& base() const noexcept { return e; }
// inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const discard_block_engine& x);    // hosted
template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, discard_block_engine& x);          // hosted
private:
    Engine e;   // *exposition only*
    size_t n;   // *exposition only*
};
}

4

#

The following relations shall hold:

0 < r

and

r <= p

.

5

#

The textual representation
consists of
 the textual representation of

e

followed by
 the value of

n

.

6

#

In addition to its behavior
pursuant to subclause

[rand.req.adapt]

,
each constructor

that is not a copy constructor
sets

n

to

0

.

#### Class template independent_bits_engine [rand.adapt.ibits]

1

#

An

independent_bits_engine

random number engine adaptor
combines random numbers
that are produced by some base engine

e

,
so as to produce random numbers
with a specified number of bits

w

.

The state

x

i

of an

independent_bits_engine

engine adaptor object

x

consists of
 the state

e

i

of its base engine

e

;
the size of the state is
 the size of

e

's state

.

2

#

The transition and generation algorithms
are described in terms
of the following integral constants:

- (2.1)Let R=e.max() - e.min() + 1 and m=⌊log2R⌋.
- (2.2)With n as determined below, let w0=⌊w/n⌋, n0=n−wmodn, y0=2w0⌊R/2w0⌋, and y1=2w0+1⌊R/2w0+1⌋.
- (2.3)Let n=⌈w/m⌉ if and only if the relation R−y0≤⌊y0/n⌋ holds as a result. Otherwise let n=1+⌈w/m⌉.

> [
> 
> Note 1
> 
> :
> 
> The relation
> 
> w=n0w0+(n−n0)(w0+1)
> 
> always holds
> 
> .
> 
> —
> 
> end note
> 
> ]

3

#

The transition algorithm
is carried out by invoking

e()

as often as needed to obtain

n0

values less than

y0+e.min()

and

n−n0

values less than

y1+e.min()

.

4

#

The generation algorithm
uses the values produced
while advancing the state as described above
to yield a quantity

S

obtained as if by the following algorithm:

S = 0;
for (k = 0; k≠n0; k += 1) {
do u = e() - e.min(); while (u≥y0);
 S = 2w0⋅S+umod2w0;
}
for (k = n0; k  ≠ n; k += 1) {
do u = e() - e.min(); while (u≥y1);
 S = 2w0+1⋅S+umod2w0+1;
}

🔗namespace std {
template<class Engine, size_t w, class UIntType>
class independent_bits_engine {
public:
// types
using result_type = UIntType;

    // engine characteristics
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return 2w−1; }
// constructors and seeding functions
constexpr independent_bits_engine();
    constexpr explicit independent_bits_engine(const Engine& e);
    constexpr explicit independent_bits_engine(Engine&& e);
    constexpr explicit independent_bits_engine(result_type s);
    template<class Sseq> constexpr explicit independent_bits_engine(Sseq& q);
    constexpr void seed();
    constexpr void seed(result_type s);
    template<class Sseq> constexpr void seed(Sseq& q);

    // equality operators
constexpr friend bool operator==(const independent_bits_engine& x, const independent_bits_engine& y);

    // generating functions
constexpr result_type operator()();
    constexpr void discard(unsigned long long z);

    // property functions
constexpr const Engine& base() const noexcept { return e; }
// inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const independent_bits_engine& x); // hosted
template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, independent_bits_engine& x);       // hosted
private:
    Engine e;   // *exposition only*
};
}

5

#

The following relations shall hold:

0 < w

and

w <= numeric_limits<result_type>​::​digits

.

6

#

The textual representation
consists of the textual representation of

e

.

#### Class template shuffle_order_engine [rand.adapt.shuf]

1

#

A

shuffle_order_engine

random number engine adaptor
produces the same random numbers
that are produced by some base engine

e

,
but delivers them in a different sequence

.

The state

x

i

of a

shuffle_order_engine

engine adaptor object

x

consists of
 the state

e

i

of its base engine

e

,
 an additional value

Y

of the type delivered by

e

,
and
 an additional sequence

V

of

k

values
 also of the type delivered by

e

.

The size of the state is
 the size of

e

's state plus

k+1

.

2

#

The transition algorithm
permutes the values produced by

e

.

The state transition is performed as follows:

- (2.1)Calculate an integer j=⌊k⋅(Y−emin)emax−emin+1⌋ .
- (2.2)Set Y to Vj and then set Vj to e().

3

#

The generation algorithm
yields the last value of

Y

produced while advancing

e

's state as described above

.

🔗namespace std {
template<class Engine, size_t k>
class shuffle_order_engine {
public:
// types
using result_type = typename Engine::result_type;

    // engine characteristics
static constexpr size_t table_size = k;
    static constexpr result_type min() { return Engine::min(); }
static constexpr result_type max() { return Engine::max(); }
// constructors and seeding functions
constexpr shuffle_order_engine();
    constexpr explicit shuffle_order_engine(const Engine& e);
    constexpr explicit shuffle_order_engine(Engine&& e);
    constexpr explicit shuffle_order_engine(result_type s);
    template<class Sseq> constexpr explicit shuffle_order_engine(Sseq& q);
    constexpr void seed();
    constexpr void seed(result_type s);
    template<class Sseq> constexpr void seed(Sseq& q);

    // equality operators
constexpr friend bool operator==(const shuffle_order_engine& x, const shuffle_order_engine& y);

    // generating functions
constexpr result_type operator()();
    constexpr void discard(unsigned long long z);

    // property functions
constexpr const Engine& base() const noexcept { return e; }
// inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const shuffle_order_engine& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, shuffle_order_engine& x);

  private:
    Engine e;           // *exposition only*
    result_type V[k];   // *exposition only*
    result_type Y;      // *exposition only*
};
}

4

#

The following relation shall hold:

0 < k

.

5

#

The textual representation
consists of
 the textual representation of

e

,
followed by
 the

k

values of

V

,
followed by
 the value of

Y

.

6

#

In addition to its behavior
pursuant to subclause

[rand.req.adapt]

,
each constructor

that is not a copy constructor
initializes

V[0], …, V[k - 1]

and

Y

,
in that order,
with values returned by successive invocations of

e()

.

### Engines and engine adaptors with predefined parameters [rand.predef]

🔗

using minstd_rand0 =
      linear_congruential_engine<uint_fast32_t, 16'807, 0, 2'147'483'647>;

1

#

Required behavior

: The

10000th

consecutive invocation
 of a default-constructed object
 of type

minstd_rand0

produces the value

1043618065

.

🔗

using minstd_rand =
      linear_congruential_engine<uint_fast32_t, 48'271, 0, 2'147'483'647>;

2

#

Required behavior

: The

10000th

consecutive invocation
 of a default-constructed object
 of type

minstd_rand

produces the value

399268537

.

🔗

using mt19937 =
      mersenne_twister_engine<uint_fast32_t, 32, 624, 397, 31,
       0x9908'b0df, 11, 0xffff'ffff, 7, 0x9d2c'5680, 15, 0xefc6'0000, 18, 1'812'433'253>;

3

#

Required behavior

: The

10000th

consecutive invocation
 of a default-constructed object
 of type

mt19937

produces the value

4123659995

.

🔗

using mt19937_64 =
      mersenne_twister_engine<uint_fast64_t, 64, 312, 156, 31,
       0xb502'6f5a'a966'19e9, 29, 0x5555'5555'5555'5555, 17,
       0x71d6'7fff'eda6'0000, 37, 0xfff7'eee0'0000'0000, 43, 6'364'136'223'846'793'005>;

4

#

Required behavior

: The

10000th

consecutive invocation
 of a default-constructed object
 of type

mt19937_64

produces the value

9981545732273789042

.

🔗

using ranlux24_base =
      subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>;

5

#

Required behavior

: The

10000th

consecutive invocation
 of a default-constructed object
 of type

ranlux24_base

produces the value

7937952

.

🔗

using ranlux48_base =
      subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>;

6

#

Required behavior

: The

10000th

consecutive invocation
 of a default-constructed object
 of type

ranlux48_base

produces the value

61839128582725

.

🔗

using ranlux24 = discard_block_engine<ranlux24_base, 223, 23>;

7

#

Required behavior

: The

10000th

consecutive invocation
 of a default-constructed object
 of type

ranlux24

produces the value

9901578

.

🔗

using ranlux48 = discard_block_engine<ranlux48_base, 389, 11>;

8

#

Required behavior

: The

10000th

consecutive invocation
 of a default-constructed object
 of type

ranlux48

produces the value

249142670248501

.

🔗

using knuth_b = shuffle_order_engine<minstd_rand0,256>;

9

#

Required behavior

: The

10000th

consecutive invocation
 of a default-constructed object
 of type

knuth_b

produces the value

1112339016

.

🔗

using default_random_engine = *implementation-defined*;

10

#

Remarks

: The choice of engine type
named by this

typedef

is

implementation-defined

.

> [
> 
> Note 1
> 
> :
> 
> The implementation
>  can select this type
>  on the basis of performance,
>  size,
>  quality,
>  or any combination of such factors,
>  so as to provide at least acceptable engine behavior
>  for relatively casual, inexpert, and/or lightweight use
> 
> .
> 
> Because different implementations
>  can select different underlying engine types,
>  code that uses this
> 
> typedef
> 
> need not generate identical sequences across implementations
> 
> .
> 
> —
> 
> end note
> 
> ]

🔗

using philox4x32 =
      philox_engine<uint_fast32_t, 32, 4, 10,
       0xCD9E8D57, 0x9E3779B9, 0xD2511F53, 0xBB67AE85>;

11

#

Required behavior

: The

10000th

consecutive invocation
a default-constructed object of type

philox4x32

produces the value

1955073260

.

🔗

using philox4x64 =
      philox_engine<uint_fast64_t, 64, 4, 10,
       0xCA5A826395121157, 0x9E3779B97F4A7C15, 0xD2E7470EE14C6C93, 0xBB67AE8584CAA73B>;

12

#

Required behavior

: The

10000th

consecutive invocation
a default-constructed object of type

philox4x64

produces the value

3409172418970261260

.

### Class random_device [rand.device]

1

#

A

random_device

uniform random bit generator
produces nondeterministic random numbers

.

2

#

If implementation limitations
prevent generating nondeterministic random numbers,
the implementation may employ a random number engine

.

🔗namespace std {
class random_device {
public:
// types
using result_type = unsigned int;

    // generator characteristics
static constexpr result_type min() { return numeric_limits<result_type>::min(); }
static constexpr result_type max() { return numeric_limits<result_type>::max(); }
// constructors
    random_device() : random_device(*implementation-defined*) {}
explicit random_device(const string& token);

    // generating functions
    result_type operator()();

    // property functions
double entropy() const noexcept;

    // no copy functions
    random_device(const random_device&) = delete;
    void operator=(const random_device&) = delete;
  };
}

🔗

explicit random_device(const string& token);

3

#

Throws

: A value of an

implementation-defined type
 derived from

exception

if the

random_device

cannot be initialized

.

4

#

Remarks

: The semantics of the

token

parameter
 and the token value used by the default constructor are

implementation-defined

.

244

🔗

double entropy() const noexcept;

5

#

Returns

: If the implementation employs a random number engine,
 returns

0.0

.

Otherwise, returns an entropy estimate

245

for the random numbers returned by

operator()

,
 in the range

min()

to

log2(max()+1)

.

🔗

result_type operator()();

6

#

Returns

: A nondeterministic random value,
 uniformly distributed
 between

min()

and

max()

(inclusive)

.

It is

implementation-defined
 how these values are generated

.

7

#

Throws

: A value of an

implementation-defined
 type derived from

exception

if a random number cannot be obtained

.

244)

The parameter is intended
   to allow an implementation to differentiate
   between different sources of randomness

.

245)

If a device has

n

states
   whose respective probabilities are

P0,…,Pn−1

,
   the device entropy

S

is defined as

S=−∑n−1i=0Pi⋅logPi

.

### Utilities [rand.util]

#### Class seed_seq [rand.util.seedseq]

🔗namespace std {
class seed_seq {
public:
// types
using result_type = uint_least32_t;

    // constructors
constexpr seed_seq() noexcept;
    template<class T>
constexpr seed_seq(initializer_list<T> il);
    template<class InputIterator>
constexpr seed_seq(InputIterator begin, InputIterator end);

    // generating functions
template<class RandomAccessIterator>
constexpr void generate(RandomAccessIterator begin, RandomAccessIterator end);

    // property functions
constexpr size_t size() const noexcept;
    template<class OutputIterator>
constexpr void param(OutputIterator dest) const;

    // no copy functions
    seed_seq(const seed_seq&) = delete;
    void operator=(const seed_seq&) = delete;

  private:
    vector<result_type> v;      // *exposition only*
};
}

🔗

constexpr seed_seq() noexcept;

1

#

Postconditions

:

v.empty()

is

true

.

🔗

template<class T>
constexpr seed_seq(initializer_list<T> il);

2

#

Constraints

:

T

is an integer type

.

3

#

Effects

: Same as

seed_seq(il.begin(), il.end())

.

🔗

template<class InputIterator>
constexpr seed_seq(InputIterator begin, InputIterator end);

4

#

Mandates

:

iterator_traits<InputIterator>​::​value_type

is an integer type

.

5

#

Preconditions

:

InputIterator

meets the

*Cpp17InputIterator*

requirements (

[input.iterators]

)

.

6

#

Effects

: Initializes

v

by the following algorithm:

for (InputIterator s = begin; s != end; ++s)
 v.push_back((*s)mod232);

🔗

template<class RandomAccessIterator>
constexpr void generate(RandomAccessIterator begin, RandomAccessIterator end);

7

#

Mandates

:

iterator_traits<RandomAccessIterator>​::​​value_type

is an unsigned integer type capable of accommodating 32-bit quantities

.

8

#

Preconditions

:

RandomAccessIterator

meets the

*Cpp17RandomAccessIterator*

requirements (

[random.access.iterators]

)
  and the requirements of a mutable iterator

.

9

#

Effects

: Does nothing if

begin == end

.

Otherwise,
 with

s=v.size()

and

n=end−begin

,
 fills the supplied range

[begin,end)

according to the following algorithm
 in which
 each operation is to be carried out modulo

232

,
 each indexing operator applied to

begin

is to be taken modulo

n

,
 and

T(x)

is defined as

x xor(x rshift27)

:

- (9.1)By way of initialization, set each element of the range to the value 0x8b8b8b8b. Additionally, for use in subsequent steps, let p=(n−t)/2 and let q=p+t, where t=(n≥623) ? 11 : (n≥68) ? 7 : (n≥39) ? 5 : (n≥7) ? 3 : (n−1)/2;
- (9.2)With m as the larger of s+1 and n, transform the elements of the range: iteratively for k=0,…,m−1, calculate values r1=1664525⋅T(begin[k]xorbegin[k+p]xorbegin[k−1])r2=r1+⎧⎪⎨⎪⎩s, k=0kmodn+v[k−1], 0<k≤skmodn, s<k and, in order, increment begin[k+p] by r1, increment begin[k+q] by r2, and set begin[k] to r2.
- (9.3)Transform the elements of the range again, beginning where the previous step ended: iteratively for k=m,…,m+n−1, calculate values r3=1566083941⋅T(begin[k]+begin[k+p]+begin[k−1])r4=r3−(kmodn) and, in order, update begin[k+p] by xoring it with r3, update begin[k+q] by xoring it with r4, and set begin[k] to r4.

10

#

Throws

: What and when

RandomAccessIterator

operations of

begin

and

end

throw

.

🔗

constexpr size_t size() const noexcept;

11

#

Returns

: The number of 32-bit units
 that would be returned
 by a call to

param()

.

12

#

Complexity

: Constant time

.

🔗

template<class OutputIterator>
constexpr void param(OutputIterator dest) const;

13

#

Mandates

: Values of type

result_type

are writable (

[iterator.requirements.general]

) to

dest

.

14

#

Preconditions

:

OutputIterator

meets the

*Cpp17OutputIterator*

requirements (

[output.iterators]

)

.

15

#

Effects

: Copies the sequence of prepared 32-bit units
 to the given destination,
 as if by executing the following statement:

copy(v.begin(), v.end(), dest);

16

#

Throws

: What and when

OutputIterator

operations of

dest

throw

.

#### Function template generate_canonical [rand.util.canonical]

🔗

template<class RealType, size_t digits, class URBG>
constexpr RealType generate_canonical(URBG& g);

1

#

Let

- (1.1)r be numeric_limits<RealType>::radix,
- (1.2)R be g.max()−g.min()+1,
- (1.3)d be the smaller of digits and numeric_limits<RealType>::digits,246
- (1.4)k be the smallest integer such that Rk≥rd, and
- (1.5)x be ⌊Rk/rd⌋.

An

*attempt*

is

k

invocations of

g()

to obtain values

g0,…,gk−1

, respectively,
and the calculation of a quantity

S

given by Formula

29.1

:

S=k−1∑i=0(gi−g.min())⋅Ri(29.1)

2

#

Effects

: Attempts are made until

S<xrd

.

> [
> 
> Note 1
> 
> :
> 
> When
> 
> R
> 
> is a power of
> 
> r
> 
> , precisely one attempt is made
> 
> .
> 
> —
> 
> end note
> 
> ]

3

#

Returns

:

⌊S/x⌋/rd

.

> [
> 
> Note 2
> 
> :
> 
> The return value
> 
> c
> 
> satisfies
> 
> 0≤c<1
> 
> .
> 
> —
> 
> end note
> 
> ]

4

#

Throws

: What and when

g

throws

.

5

#

Complexity

: Exactly

k

invocations of

g

per attempt

.

6

#

> [
> 
> Note 3
> 
> :
> 
> If the values
> 
> gi
> 
> produced by
> 
> g
> 
> are uniformly distributed,
> the instantiation's results are distributed as uniformly as possible
> 
> .
> 
> Obtaining a value in this way
> can be a useful step
> in the process of transforming
> a value generated by a uniform random bit generator
> into a value
> that can be delivered by a random number distribution
> 
> .
> 
> —
> 
> end note
> 
> ]

7

#

> [
> 
> Note 4
> 
> :
> 
> When
> 
> R
> 
> is a power of
> 
> r
> 
> ,
> an implementation can avoid using an arithmetic type that is wider
> than the output when computing
> 
> S
> 
> .
> 
> —
> 
> end note
> 
> ]

246)

d

is introduced to avoid any attempt
  to produce more bits of randomness
  than can be held in

RealType

.

### Random number distribution class templates [rand.dist]

#### General [rand.dist.general]

1

#

Each type instantiated
from a class template specified in

[rand.dist]

meets the requirements
of a

random number distribution

type

.

2

#

Descriptions are provided in

[rand.dist]

only for distribution operations
that are not described in

[rand.req.dist]

or for operations where there is additional semantic information

.

In particular,
declarations for copy constructors,
for copy assignment operators,
for streaming operators,
and for equality and inequality operators
are not shown in the synopses

.

3

#

The algorithms for producing each
of the specified distributions are

implementation-defined

.

4

#

The value of each probability density function

p(z)

and of each discrete probability function

P(zi)

specified in this subclause
is

0

everywhere outside its stated domain

.

#### Uniform distributions [rand.dist.uni]

#### Class template uniform_int_distribution [rand.dist.uni.int]

1

#

A

uniform_int_distribution

random number distribution
produces random integers

i

,

a  ≤ i  ≤ b

,
distributed according to
the constant discrete probability function in Formula

29.2

.

P(i|a,b)=1/(b−a+1)(29.2)

🔗namespace std {
template<class IntType = int>
class uniform_int_distribution {
public:
// types
using result_type = IntType;
    using param_type  = *unspecified*;

    // constructors and reset functions
constexpr uniform_int_distribution() : uniform_int_distribution(0) {}
constexpr explicit uniform_int_distribution(IntType a, IntType b = numeric_limits<IntType>::max());
    constexpr explicit uniform_int_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const uniform_int_distribution& x, const uniform_int_distribution& y);

    // generating functions
template<class URBG>
constexpr result_type operator()(URBG& g);
    template<class URBG>
constexpr result_type operator()(URBG& g, const param_type& parm);

    // property functions
constexpr result_type a() const;
    constexpr result_type b() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os,            // hosted
const uniform_int_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is,            // hosted
                   uniform_int_distribution& x);
  };
}

🔗

constexpr explicit uniform_int_distribution(IntType a, IntType b = numeric_limits<IntType>::max());

2

#

Preconditions

:

a  ≤ b

.

3

#

Remarks

:

a

and

b

correspond to the respective parameters of the distribution

.

🔗

constexpr result_type a() const;

4

#

Returns

: The value of the

a

parameter
 with which the object was constructed

.

🔗

constexpr result_type b() const;

5

#

Returns

: The value of the

b

parameter
 with which the object was constructed

.

#### Class template uniform_real_distribution [rand.dist.uni.real]

1

#

A

uniform_real_distribution

random number distribution
produces random numbers

x

,

a≤x<b

,
distributed according to
the constant probability density function in Formula

29.3

.

p(x|a,b)=1/(b−a)(29.3)

> [
> 
> Note 1
> 
> :
> 
> This implies that
> 
> p(x | a,b)
> 
> is undefined when
> 
> a == b
> 
> .
> 
> —
> 
> end note
> 
> ]

🔗namespace std {
template<class RealType = double>
class uniform_real_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructors and reset functions
constexpr uniform_real_distribution() : uniform_real_distribution(0.0) {}
constexpr explicit uniform_real_distribution(RealType a, RealType b = 1.0);
    constexpr explicit uniform_real_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const uniform_real_distribution& x,
                           const uniform_real_distribution& y);

    // generating functions
template<class URBG>
constexpr result_type operator()(URBG& g);
    template<class URBG>
constexpr result_type operator()(URBG& g, const param_type& parm);

    // property functions
constexpr result_type a() const;
    constexpr result_type b() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const uniform_real_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, uniform_real_distribution& x);
  };
}

🔗

constexpr explicit uniform_real_distribution(RealType a, RealType b = 1.0);

2

#

Preconditions

:

a  ≤ b

and

b−a≤numeric_limits<RealType>::max()

.

3

#

Remarks

:

a

and

b

correspond to the respective parameters of the distribution

.

🔗

constexpr result_type a() const;

4

#

Returns

: The value of the

a

parameter
 with which the object was constructed

.

🔗

constexpr result_type b() const;

5

#

Returns

: The value of the

b

parameter
 with which the object was constructed

.

#### Bernoulli distributions [rand.dist.bern]

#### Class bernoulli_distribution [rand.dist.bern.bernoulli]

1

#

A

bernoulli_distribution

random number distribution
produces

bool

values

b

distributed according to
the discrete probability function in Formula

29.4

.

P(b|p)={p if b=true1−p if b=false(29.4)

🔗namespace std {
class bernoulli_distribution {
public:
// types
using result_type = bool;
    using param_type  = *unspecified*;

    // constructors and reset functions
constexpr bernoulli_distribution() : bernoulli_distribution(0.5) {}
constexpr explicit bernoulli_distribution(double p);
    constexpr explicit bernoulli_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const bernoulli_distribution& x, const bernoulli_distribution& y);

    // generating functions
template<class URBG>
constexpr result_type operator()(URBG& g);
    template<class URBG>
constexpr result_type operator()(URBG& g, const param_type& parm);

    // property functions
constexpr double p() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const bernoulli_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, bernoulli_distribution& x);
  };
}

🔗

constexpr explicit bernoulli_distribution(double p);

2

#

Preconditions

:

0  ≤ p  ≤ 1

.

3

#

Remarks

:

p

corresponds to the parameter of the distribution

.

🔗

constexpr double p() const;

4

#

Returns

: The value of the

p

parameter
 with which the object was constructed

.

#### Class template binomial_distribution [rand.dist.bern.bin]

1

#

A

binomial_distribution

random number distribution
produces integer values

i  ≥ 0

distributed according to
the discrete probability function in Formula

29.5

.

P(i|t,p)=(ti)⋅pi⋅(1−p)t−i(29.5)

🔗namespace std {
template<class IntType = int>
class binomial_distribution {
public:
// types
using result_type = IntType;
    using param_type  = *unspecified*;

    // constructors and reset functions
constexpr binomial_distribution() : binomial_distribution(1) {}
constexpr explicit binomial_distribution(IntType t, double p = 0.5);
    constexpr explicit binomial_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const binomial_distribution& x, const binomial_distribution& y);

    // generating functions
template<class URBG>
constexpr result_type operator()(URBG& g);
    template<class URBG>
constexpr result_type operator()(URBG& g, const param_type& parm);

    // property functions
constexpr IntType t() const;
    constexpr double p() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const binomial_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, binomial_distribution& x);
  };
}

🔗

constexpr explicit binomial_distribution(IntType t, double p = 0.5);

2

#

Preconditions

:

0  ≤ p  ≤ 1

and

0  ≤ t

.

3

#

Remarks

:

t

and

p

correspond to the respective parameters of the distribution

.

🔗

constexpr IntType t() const;

4

#

Returns

: The value of the

t

parameter
 with which the object was constructed

.

🔗

constexpr double p() const;

5

#

Returns

: The value of the

p

parameter
 with which the object was constructed

.

#### Class template geometric_distribution [rand.dist.bern.geo]

1

#

A

geometric_distribution

random number distribution
produces integer values

i  ≥ 0

distributed according to
the discrete probability function in Formula

29.6

.

P(i|p)=p⋅(1−p)i(29.6)

🔗namespace std {
template<class IntType = int>
class geometric_distribution {
public:
// types
using result_type = IntType;
    using param_type  = *unspecified*;

    // constructors and reset functions
constexpr geometric_distribution() : geometric_distribution(0.5) {}
constexpr explicit geometric_distribution(double p);
    constexpr explicit geometric_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const geometric_distribution& x, const geometric_distribution& y);

    // generating functions
template<class URBG>
constexpr result_type operator()(URBG& g);
    template<class URBG>
constexpr result_type operator()(URBG& g, const param_type& parm);

    // property functions
constexpr double p() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const geometric_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, geometric_distribution& x);
  };
}

🔗

constexpr explicit geometric_distribution(double p);

2

#

Preconditions

:

0<p<1

.

3

#

Remarks

:

p

corresponds to the parameter of the distribution

.

🔗

constexpr double p() const;

4

#

Returns

: The value of the

p

parameter
 with which the object was constructed

.

#### Class template negative_binomial_distribution [rand.dist.bern.negbin]

1

#

A

negative_binomial_distribution

random number distribution
produces random integers

i  ≥ 0

distributed according to
the discrete probability function in Formula

29.7

.

P(i|k,p)=(k+i−1i)⋅pk⋅(1−p)i(29.7)

> [
> 
> Note 1
> 
> :
> 
> This implies that
> 
> P(i | k,p)
> 
> is undefined when
> 
> p == 1
> 
> .
> 
> —
> 
> end note
> 
> ]

🔗namespace std {
template<class IntType = int>
class negative_binomial_distribution {
public:
// types
using result_type = IntType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr negative_binomial_distribution() : negative_binomial_distribution(1) {}
constexpr explicit negative_binomial_distribution(IntType k, double p = 0.5);
    constexpr explicit negative_binomial_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const negative_binomial_distribution& x,
                           const negative_binomial_distribution& y);

    // generating functions
template<class URBG>
constexpr result_type operator()(URBG& g);
    template<class URBG>
constexpr result_type operator()(URBG& g, const param_type& parm);

    // property functions
constexpr IntType k() const;
    constexpr double p() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const negative_binomial_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, negative_binomial_distribution& x);
  };
}

🔗

constexpr explicit negative_binomial_distribution(IntType k, double p = 0.5);

2

#

Preconditions

:

0<p≤1

and

0<k

.

3

#

Remarks

:

k

and

p

correspond to the respective parameters of the distribution

.

🔗

constexpr IntType k() const;

4

#

Returns

: The value of the

k

parameter
 with which the object was constructed

.

🔗

constexpr double p() const;

5

#

Returns

: The value of the

p

parameter
 with which the object was constructed

.

#### Poisson distributions [rand.dist.pois]

#### Class template poisson_distribution [rand.dist.pois.poisson]

1

#

A

poisson_distribution

random number distribution
produces integer values

i  ≥ 0

distributed according to
the discrete probability function in Formula

29.8

.

P(i|μ)=e−μμii!(29.8)

The distribution parameter

μ

is also known as this distribution's

*mean*

.

🔗namespace std {
template<class IntType = int>
class poisson_distribution {
public:
// types
using result_type = IntType;
    using param_type  = *unspecified*;

    // constructors and reset functions
constexpr poisson_distribution() : poisson_distribution(1.0) {}
constexpr explicit poisson_distribution(double mean);
    constexpr explicit poisson_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const poisson_distribution& x, const poisson_distribution& y);

    // generating functions
template<class URBG>
constexpr result_type operator()(URBG& g);
    template<class URBG>
constexpr result_type operator()(URBG& g, const param_type& parm);

    // property functions
constexpr double mean() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const poisson_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, poisson_distribution& x);
  };
}

🔗

constexpr explicit poisson_distribution(double mean);

2

#

Preconditions

:

0<mean

.

3

#

Remarks

:

mean

corresponds to the parameter of the distribution

.

🔗

constexpr double mean() const;

4

#

Returns

: The value of the

mean

.

#### Class template exponential_distribution [rand.dist.pois.exp]

1

#

An

exponential_distribution

random number distribution
produces random numbers

x>0

distributed according to
the probability density function in Formula

29.9

.

p(x|λ)=λe−λx(29.9)

🔗namespace std {
template<class RealType = double>
class exponential_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructors and reset functions
constexpr exponential_distribution() : exponential_distribution(1.0) {}
constexpr explicit exponential_distribution(RealType lambda);
    constexpr explicit exponential_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const exponential_distribution& x, const exponential_distribution& y);

    // generating functions
template<class URBG>
constexpr result_type operator()(URBG& g);
    template<class URBG>
constexpr result_type operator()(URBG& g, const param_type& parm);

    // property functions
constexpr RealType lambda() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const exponential_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, exponential_distribution& x);
  };
}

🔗

constexpr explicit exponential_distribution(RealType lambda);

2

#

Preconditions

:

0<lambda

.

3

#

Remarks

:

lambda

corresponds to the parameter of the distribution

.

🔗

constexpr RealType lambda() const;

4

#

Returns

: The value of the

lambda

.

#### Class template gamma_distribution [rand.dist.pois.gamma]

1

#

A

gamma_distribution

random number distribution
produces random numbers

x>0

distributed according to
the probability density function in Formula

29.10

.

p(x|α,β)=e−x/ββα⋅Γ(α)⋅xα−1(29.10)

🔗namespace std {
template<class RealType = double>
class gamma_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructors and reset functions
constexpr gamma_distribution() : gamma_distribution(1.0) {}
constexpr explicit gamma_distribution(RealType alpha, RealType beta = 1.0);
    constexpr explicit gamma_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const gamma_distribution& x, const gamma_distribution& y);

    // generating functions
template<class URBG>
constexpr result_type operator()(URBG& g);
    template<class URBG>
constexpr result_type operator()(URBG& g, const param_type& parm);

    // property functions
constexpr RealType alpha() const;
    constexpr RealType beta() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const gamma_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, gamma_distribution& x);
  };
}

🔗

constexpr explicit gamma_distribution(RealType alpha, RealType beta = 1.0);

2

#

Preconditions

:

0<alpha

and

0<beta

.

3

#

Remarks

:

alpha

and

beta

correspond to the parameters of the distribution

.

🔗

constexpr RealType alpha() const;

4

#

Returns

: The value of the

alpha

.

🔗

constexpr RealType beta() const;

5

#

Returns

: The value of the

beta

.

#### Class template weibull_distribution [rand.dist.pois.weibull]

1

#

A

weibull_distribution

random number distribution
produces random numbers

x  ≥ 0

distributed according to
the probability density function in Formula

29.11

.

p(x|a,b)=ab⋅(xb)a−1⋅exp(−(xb)a)(29.11)

🔗namespace std {
template<class RealType = double>
class weibull_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr weibull_distribution() : weibull_distribution(1.0) {}
constexpr explicit weibull_distribution(RealType a, RealType b = 1.0);
    constexpr explicit weibull_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const weibull_distribution& x, const weibull_distribution& y);

    // generating functions
template<class URBG>
constexpr result_type operator()(URBG& g);
    template<class URBG>
constexpr result_type operator()(URBG& g, const param_type& parm);

    // property functions
constexpr RealType a() const;
    constexpr RealType b() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const weibull_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, weibull_distribution& x);
  };
}

🔗

constexpr explicit weibull_distribution(RealType a, RealType b = 1.0);

2

#

Preconditions

:

0<a

and

0<b

.

3

#

Remarks

:

a

and

b

correspond to the respective parameters of the distribution

.

🔗

constexpr RealType a() const;

4

#

Returns

: The value of the

a

.

🔗

constexpr RealType b() const;

5

#

Returns

: The value of the

b

.

#### Class template extreme_value_distribution [rand.dist.pois.extreme]

1

#

An

extreme_value_distribution

random number distribution
produces random numbers

x

distributed according to
the probability density function in Formula

29.12

.

247

p(x|a,b)=1b⋅exp(a−xb−exp(a−xb))(29.12)

🔗namespace std {
template<class RealType = double>
class extreme_value_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr extreme_value_distribution() : extreme_value_distribution(0.0) {}
constexpr explicit extreme_value_distribution(RealType a, RealType b = 1.0);
    constexpr explicit extreme_value_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const extreme_value_distribution& x,
                           const extreme_value_distribution& y);

    // property functions
constexpr RealType a() const;
    constexpr RealType b() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const extreme_value_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, extreme_value_distribution& x);
  };
}

🔗

constexpr explicit extreme_value_distribution(RealType a, RealType b = 1.0);

2

#

Preconditions

:

0<b

.

3

#

Remarks

:

a

and

b

correspond to the respective parameters of the distribution

.

🔗

constexpr RealType a() const;

4

#

Returns

: The value of the

a

.

🔗

constexpr RealType b() const;

5

#

Returns

: The value of the

b

.

247)

The distribution corresponding to
 this probability density function
 is also known
 (with a possible change of variable)
 as the Gumbel Type I,
 the log-Weibull,
 or the Fisher-Tippett Type I
 distribution

.

#### Normal distributions [rand.dist.norm]

#### Class template normal_distribution [rand.dist.norm.normal]

1

#

A

normal_distribution

random number distribution
produces random numbers

x

distributed according to
the probability density function in Formula

29.13

.

p(x|μ,σ)=1σ√2π⋅exp(−(x−μ)22σ2)(29.13)

The distribution parameters

μ

and

σ

are also known as this distribution's

*mean*

and

*standard deviation*

.

🔗namespace std {
template<class RealType = double>
class normal_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructors and reset functions
constexpr normal_distribution() : normal_distribution(0.0) {}
constexpr explicit normal_distribution(RealType mean, RealType stddev = 1.0);
    constexpr explicit normal_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const normal_distribution& x, const normal_distribution& y);

    // property functions
constexpr RealType mean() const;
    constexpr RealType stddev() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const normal_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, normal_distribution& x);
  };
}

🔗

constexpr explicit normal_distribution(RealType mean, RealType stddev = 1.0);

2

#

Preconditions

:

0<stddev

.

3

#

Remarks

:

mean

and

stddev

correspond to the respective parameters of the distribution

.

🔗

constexpr RealType mean() const;

4

#

Returns

: The value of the

mean

.

🔗

constexpr RealType stddev() const;

5

#

Returns

: The value of the

stddev

.

#### Class template lognormal_distribution [rand.dist.norm.lognormal]

1

#

A

lognormal_distribution

random number distribution
produces random numbers

x>0

distributed according to
the probability density function in Formula

29.14

.

p(x|m,s)=1sx√2π⋅exp(−(lnx−m)22s2)(29.14)

🔗namespace std {
template<class RealType = double>
class lognormal_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr lognormal_distribution() : lognormal_distribution(0.0) {}
constexpr explicit lognormal_distribution(RealType m, RealType s = 1.0);
    constexpr explicit lognormal_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const lognormal_distribution& x, const lognormal_distribution& y);

    // property functions
constexpr RealType m() const;
    constexpr RealType s() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const lognormal_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, lognormal_distribution& x);
  };
}

🔗

constexpr explicit lognormal_distribution(RealType m, RealType s = 1.0);

2

#

Preconditions

:

0<s

.

3

#

Remarks

:

m

and

s

correspond to the respective parameters of the distribution

.

🔗

constexpr RealType m() const;

4

#

Returns

: The value of the

m

.

🔗

constexpr RealType s() const;

5

#

Returns

: The value of the

s

.

#### Class template chi_squared_distribution [rand.dist.norm.chisq]

1

#

A

chi_squared_distribution

random number distribution
produces random numbers

x>0

distributed according to
the probability density function in Formula

29.15

.

p(x|n)=x(n/2)−1⋅e−x/2Γ(n/2)⋅2n/2(29.15)

🔗namespace std {
template<class RealType = double>
class chi_squared_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr chi_squared_distribution() : chi_squared_distribution(1.0) {}
constexpr explicit chi_squared_distribution(RealType n);
    constexpr explicit chi_squared_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const chi_squared_distribution& x, const chi_squared_distribution& y);

    // property functions
constexpr RealType n() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const chi_squared_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, chi_squared_distribution& x);
  };
}

🔗

constexpr explicit chi_squared_distribution(RealType n);

2

#

Preconditions

:

0<n

.

3

#

Remarks

:

n

corresponds to the parameter of the distribution

.

🔗

constexpr RealType n() const;

4

#

Returns

: The value of the

n

.

#### Class template cauchy_distribution [rand.dist.norm.cauchy]

1

#

A

cauchy_distribution

random number distribution
produces random numbers

x

distributed according to
the probability density function in Formula

29.16

.

p(x|a,b)=(πb(1+(x−ab)2))−1(29.16)

🔗namespace std {
template<class RealType = double>
class cauchy_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr cauchy_distribution() : cauchy_distribution(0.0) {}
constexpr explicit cauchy_distribution(RealType a, RealType b = 1.0);
    constexpr explicit cauchy_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const cauchy_distribution& x, const cauchy_distribution& y);

    // property functions
constexpr RealType a() const;
    constexpr RealType b() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const cauchy_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, cauchy_distribution& x);
  };
}

🔗

constexpr explicit cauchy_distribution(RealType a, RealType b = 1.0);

2

#

Preconditions

:

0<b

.

3

#

Remarks

:

a

and

b

correspond to the respective parameters of the distribution

.

🔗

constexpr RealType a() const;

4

#

Returns

: The value of the

a

.

🔗

constexpr RealType b() const;

5

#

Returns

: The value of the

b

.

#### Class template fisher_f_distribution [rand.dist.norm.f]

1

#

A

fisher_f_distribution

random number distribution
produces random numbers

x  ≥ 0

distributed according to
the probability density function in Formula

29.17

.

p(x|m,n)=Γ((m+n)/2)Γ(m/2)Γ(n/2)⋅(mn)m/2⋅x(m/2)−1⋅(1+mxn)−(m+n)/2(29.17)

🔗namespace std {
template<class RealType = double>
class fisher_f_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr fisher_f_distribution() : fisher_f_distribution(1.0) {}
constexpr explicit fisher_f_distribution(RealType m, RealType n = 1.0);
    constexpr explicit fisher_f_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const fisher_f_distribution& x, const fisher_f_distribution& y);

    // property functions
constexpr RealType m() const;
    constexpr RealType n() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const fisher_f_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, fisher_f_distribution& x);
  };
}

🔗

constexpr explicit fisher_f_distribution(RealType m, RealType n = 1);

2

#

Preconditions

:

0<m

and

0<n

.

3

#

Remarks

:

m

and

n

correspond to the respective parameters of the distribution

.

🔗

constexpr RealType m() const;

4

#

Returns

: The value of the

m

.

🔗

constexpr RealType n() const;

5

#

Returns

: The value of the

n

.

#### Class template student_t_distribution [rand.dist.norm.t]

1

#

A

student_t_distribution

x

distributed according to
the probability density function in Formula

29.18

.

p(x|n)=1√nπ⋅Γ((n+1)/2)Γ(n/2)⋅(1+x2n)−(n+1)/2(29.18)

🔗namespace std {
template<class RealType = double>
class student_t_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr student_t_distribution() : student_t_distribution(1.0) {}
constexpr explicit student_t_distribution(RealType n);
    constexpr explicit student_t_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const student_t_distribution& x, const student_t_distribution& y);

    // property functions
constexpr RealType n() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const student_t_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, student_t_distribution& x);
  };
}

🔗

constexpr explicit student_t_distribution(RealType n);

2

#

Preconditions

:

0<n

.

3

#

Remarks

:

n

corresponds to the parameter of the distribution

.

🔗

constexpr RealType n() const;

4

#

Returns

: The value of the

n

.

#### Sampling distributions [rand.dist.samp]

#### Class template discrete_distribution [rand.dist.samp.discrete]

1

#

A

discrete_distribution

random number distribution
produces random integers

i

,

0≤i<n

,
distributed according to
the discrete probability function in Formula

29.19

.

P(i|p0,…,pn−1)=pi(29.19)

2

#

Unless specified otherwise,
the distribution parameters are calculated as:

pk=wk/S

for

k=0,…,n−1

,
in which the values

wk

,
commonly known as the

*weights*

, shall be non-negative, non-NaN, and non-infinity

.

Moreover, the following relation shall hold:

0<S=w0+⋯+wn−1

.

🔗namespace std {
template<class IntType = int>
class discrete_distribution {
public:
// types
using result_type = IntType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr discrete_distribution();
    template<class InputIterator>
constexpr discrete_distribution(InputIterator firstW, InputIterator lastW);
    constexpr discrete_distribution(initializer_list<double> wl);
    template<class UnaryOperation>
constexpr discrete_distribution(size_t nw, double xmin, double xmax, UnaryOperation fw);
    constexpr explicit discrete_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const discrete_distribution& x, const discrete_distribution& y);

    // property functions
constexpr vector<double> probabilities() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const discrete_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, discrete_distribution& x);
  };
}

🔗

constexpr discrete_distribution();

3

#

Effects

: Constructs a

discrete_distribution

object
with

n=1

and

p0=1

.

> [
> 
> Note 1
> 
> :
> 
> Such an object will always deliver the value
> 
> 0
> 
> .
> 
> —
> 
> end note
> 
> ]

🔗

template<class InputIterator>
constexpr discrete_distribution(InputIterator firstW, InputIterator lastW);

4

#

Mandates

:

is_convertible_v<iterator_traits<InputIterator>​::​value_type,
double>

is

true

.

5

#

Preconditions

:

InputIterator

meets the

*Cpp17InputIterator*

requirements (

[input.iterators]

)

.

If

firstW == lastW

,
 let

n=1

and

w0=1

.

Otherwise,

[firstW, lastW)

forms a sequence

w

of length

n>0

.

6

#

Effects

: Constructs a

discrete_distribution

object
with probabilities given by the Formula

29.19

.

🔗

constexpr discrete_distribution(initializer_list<double> wl);

7

#

Effects

: Same as

discrete_distribution(wl.begin(), wl.end())

.

🔗

template<class UnaryOperation>
constexpr discrete_distribution(size_t nw, double xmin, double xmax, UnaryOperation fw);

8

#

Mandates

:

is_invocable_r_v<double, UnaryOperation&, double>

is

true

.

9

#

Preconditions

: If

nw=0

, let

n=1

, otherwise let

n=nw

.

The relation

0<δ=(xmax−xmin)/n

holds

.

10

#

Effects

: Constructs a

discrete_distribution

object
 with probabilities given by the formula above,
 using the following values:
 If

nw=0

,
 let

w0=1

.

Otherwise,
 let

wk=fw(xmin+k⋅δ+δ/2)

for

k=0,…,n−1

.

11

#

Complexity

: The number of invocations of

fw

does not exceed

n

.

🔗

constexpr vector<double> probabilities() const;

12

#

Returns

: A

vector<double>

whose

size

member returns

n

and whose

operator[]

member returns

pk

when invoked with argument

k

for

k=0,…,n−1

.

#### Class template piecewise_constant_distribution [rand.dist.samp.pconst]

1

#

A

piecewise_constant_distribution

x

,

b0≤x<bn

,
uniformly distributed over each subinterval

[bi,bi+1)

according to the probability density function in Formula

29.20

.

p(x|b0,…,bn,ρ0,…,ρn−1)=ρi , for bi≤x<bi+1(29.20)

2

#

The

n+1

distribution parameters

bi

,
also known as this distribution's

*interval boundaries*

, shall satisfy the relation

bi<bi+1

for

i=0,…,n−1

.

Unless specified otherwise,
the remaining

n

distribution parameters are calculated as:

ρk=wkS⋅(bk+1−bk) for k=0,…,n−1 ,

in which the values

wk

,
commonly known as the

*weights*

, shall be non-negative, non-NaN, and non-infinity

.

Moreover, the following relation shall hold:

0<S=w0+⋯+wn−1

.

🔗namespace std {
template<class RealType = double>
class piecewise_constant_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr piecewise_constant_distribution();
    template<class InputIteratorB, class InputIteratorW>
constexpr piecewise_constant_distribution(InputIteratorB firstB, InputIteratorB lastB,
                                      InputIteratorW firstW);
    template<class UnaryOperation>
constexpr piecewise_constant_distribution(initializer_list<RealType> bl, UnaryOperation fw);
    template<class UnaryOperation>
constexpr piecewise_constant_distribution(size_t nw, RealType xmin, RealType xmax,
                                      UnaryOperation fw);
    constexpr explicit piecewise_constant_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const piecewise_constant_distribution& x,
                           const piecewise_constant_distribution& y);

    // property functions
constexpr vector<result_type> intervals() const;
    constexpr vector<result_type> densities() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const piecewise_constant_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, piecewise_constant_distribution& x);
  };
}

🔗

constexpr piecewise_constant_distribution();

3

#

Effects

: Constructs a

piecewise_constant_distribution

object
 with

n=1

,

ρ0=1

,

b0=0

,
 and

b1=1

.

🔗

template<class InputIteratorB, class InputIteratorW>
constexpr piecewise_constant_distribution(InputIteratorB firstB, InputIteratorB lastB,
                                  InputIteratorW firstW);

4

#

Mandates

: Both of

- (4.1)is_convertible_v<iterator_traits<InputIteratorB>::value_type, double>
- (4.2)is_convertible_v<iterator_traits<InputIteratorW>::value_type, double>

are

true

.

5

#

Preconditions

:

InputIteratorB

and

InputIteratorW

each meet the

*Cpp17InputIterator*

requirements (

[input.iterators]

)

.

If

firstB == lastB

or

++firstB == lastB

,
 let

n=1

,

w0=1

,

b0=0

,
 and

b1=1

.

Otherwise,

[firstB, lastB)

forms a sequence

b

of length

n+1

,
 the length of the sequence

w

starting from

firstW

is at least

n

,
 and any

wk

for

k  ≥ n

are ignored by the distribution

.

6

#

Effects

: Constructs a

piecewise_constant_distribution

object
 with parameters as specified above

.

🔗

template<class UnaryOperation>
constexpr piecewise_constant_distribution(initializer_list<RealType> bl, UnaryOperation fw);

7

#

Mandates

:

is_invocable_r_v<double, UnaryOperation&, double>

is

true

.

8

#

Effects

: Constructs a

piecewise_constant_distribution

object
 with parameters taken or calculated
 from the following values:
 If

bl.size()<2

,
 let

n=1

,

w0=1

,

b0=0

,
 and

b1=1

.

Otherwise,
 let

[bl.begin(), bl.end())

form a sequence

b0,…,bn

,
 and
 let

wk=fw((bk+1+bk)/2)

for

k=0,…,n−1

.

9

#

Complexity

: The number of invocations of

fw

does not exceed

n

.

🔗

template<class UnaryOperation>
constexpr piecewise_constant_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw);

10

#

Mandates

:

is_invocable_r_v<double, UnaryOperation&, double>

is

true

.

11

#

Preconditions

: If

nw=0

, let

n=1

, otherwise let

n=nw

.

The relation

0<δ=(xmax−xmin)/n

holds

.

12

#

Effects

: Constructs a

piecewise_constant_distribution

object
 with parameters taken or calculated
 from the following values:
 Let

bk=xmin+k⋅δ

for

k=0,…,n

,
 and

wk=fw(bk+δ/2)

for

k=0,…,n−1

.

13

#

Complexity

: The number of invocations of

fw

does not exceed

n

.

🔗

constexpr vector<result_type> intervals() const;

14

#

Returns

: A

vector<result_type>

whose

size

member returns

n+1

and whose

operator[]

member returns

bk

when invoked with argument

k

for

k=0,…,n

.

🔗

constexpr vector<result_type> densities() const;

15

#

Returns

: A

vector<result_type>

whose

size

member returns

n

and whose

operator[]

member returns

ρk

when invoked with argument

k

for

k=0,…,n−1

.

#### Class template piecewise_linear_distribution [rand.dist.samp.plinear]

1

#

A

piecewise_linear_distribution

x

,

b0≤x<bn

,
distributed over each subinterval

[bi,bi+1)

according to the probability density function in Formula

29.21

.

p(x|b0,…,bn,ρ0,…,ρn)=ρi⋅bi+1−xbi+1−bi+ρi+1⋅x−bibi+1−bi , for bi≤x<bi+1.(29.21)

2

#

The

n+1

distribution parameters

bi

,
also known as this distribution's

*interval boundaries*

, shall satisfy the relation

bi<bi+1

for

i=0,…,n−1

.

Unless specified otherwise,
the remaining

n+1

distribution parameters are calculated as

ρk=wk/S

for

k=0,…,n

, in which the values

wk

,
commonly known as the

*weights at boundaries*

, shall be non-negative, non-NaN, and non-infinity

.

Moreover, the following relation shall hold:

0<S=12⋅n−1∑k=0(wk+wk+1)⋅(bk+1−bk) .

🔗namespace std {
template<class RealType = double>
class piecewise_linear_distribution {
public:
// types
using result_type = RealType;
    using param_type  = *unspecified*;

    // constructor and reset functions
constexpr piecewise_linear_distribution();
    template<class InputIteratorB, class InputIteratorW>
constexpr piecewise_linear_distribution(InputIteratorB firstB, InputIteratorB lastB,
                                    InputIteratorW firstW);
    template<class UnaryOperation>
constexpr piecewise_linear_distribution(initializer_list<RealType> bl, UnaryOperation fw);
    template<class UnaryOperation>
constexpr piecewise_linear_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw);
    constexpr explicit piecewise_linear_distribution(const param_type& parm);
    constexpr void reset();

    // equality operators
constexpr friend bool operator==(const piecewise_linear_distribution& x,
                           const piecewise_linear_distribution& y);

    // property functions
constexpr vector<result_type> intervals() const;
    constexpr vector<result_type> densities() const;
    constexpr param_type param() const;
    constexpr void param(const param_type& parm);
    constexpr result_type min() const;
    constexpr result_type max() const;

    // inserters and extractors
template<class charT, class traits>
friend basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const piecewise_linear_distribution& x);
    template<class charT, class traits>
friend basic_istream<charT, traits>&
operator>>(basic_istream<charT, traits>& is, piecewise_linear_distribution& x);
  };
}

🔗

constexpr piecewise_linear_distribution();

3

#

Effects

: Constructs a

piecewise_linear_distribution

object
 with

n=1

,

ρ0=ρ1=1

,

b0=0

,
 and

b1=1

.

🔗

template<class InputIteratorB, class InputIteratorW>
constexpr piecewise_linear_distribution(InputIteratorB firstB, InputIteratorB lastB,
                                InputIteratorW firstW);

4

#

Mandates

: Both of

- (4.1)is_convertible_v<iterator_traits<InputIteratorB>::value_type, double>
- (4.2)is_convertible_v<iterator_traits<InputIteratorW>::value_type, double>

are

true

.

5

#

Preconditions

:

InputIteratorB

and

InputIteratorW

each meet the

*Cpp17InputIterator*

requirements (

[input.iterators]

)

.

If

firstB == lastB

or

++firstB == lastB

,
 let

n=1

,

ρ0=ρ1=1

,

b0=0

,
 and

b1=1

.

Otherwise,

[firstB, lastB)

forms a sequence

b

of length

n+1

,
 the length of the sequence

w

starting from

firstW

is at least

n+1

,
 and any

wk

for

k≥n+1

are ignored by the distribution

.

6

#

Effects

: Constructs a

piecewise_linear_distribution

object
 with parameters as specified above

.

🔗

template<class UnaryOperation>
constexpr piecewise_linear_distribution(initializer_list<RealType> bl, UnaryOperation fw);

7

#

Mandates

:

is_invocable_r_v<double, UnaryOperation&, double>

is

true

.

8

#

Effects

: Constructs a

piecewise_linear_distribution

object
 with parameters taken or calculated
 from the following values:
 If

bl.size()<2

,
 let

n=1

,

ρ0=ρ1=1

,

b0=0

,
 and

b1=1

.

Otherwise,
 let

[bl.begin(), bl.end())

form a sequence

b0,…,bn

,
 and
 let

wk=fw(bk)

for

k=0,…,n

.

9

#

Complexity

: The number of invocations of

fw

does not exceed

n+1

.

🔗

template<class UnaryOperation>
constexpr piecewise_linear_distribution(size_t nw, RealType xmin, RealType xmax, UnaryOperation fw);

10

#

Mandates

:

is_invocable_r_v<double, UnaryOperation&, double>

is

true

.

11

#

Preconditions

: If

nw=0

, let

n=1

, otherwise let

n=nw

.

The relation

0<δ=(xmax−xmin)/n

holds

.

12

#

Effects

: Constructs a

piecewise_linear_distribution

object
 with parameters taken or calculated
 from the following values:
 Let

bk=xmin+k⋅δ

for

k=0,…,n

,
 and

wk=fw(bk)

for

k=0,…,n

.

13

#

Complexity

: The number of invocations of

fw

does not exceed

n+1

.

🔗

constexpr vector<result_type> intervals() const;

14

#

Returns

: A

vector<result_type>

whose

size

member returns

n+1

and whose

operator[]

member returns

bk

when invoked with argument

k

for

k=0,…,n

.

🔗

constexpr vector<result_type> densities() const;

15

#

Returns

: A

vector<result_type>

whose

size

member returns

n

and whose

operator[]

member returns

ρk

when invoked with argument

k

for

k=0,…,n

.

### Low-quality random number generation [c.math.rand]

1

#

> [
> 
> Note 1
> 
> :
> 
> The header
> 
> <cstdlib>
> 
> declares the functions described in this subclause
> 
> .
> 
> —
> 
> end note
> 
> ]

🔗

int rand();
void srand(unsigned int seed);

2

#

Effects

: The

rand

and

srand

functions have the semantics specified in the C standard library

.

3

#

Remarks

: The implementation
may specify that particular library functions may call

rand

.

It is

implementation-defined
whether the

rand

function
may introduce data races (

[res.on.data.races]

)

.

> [
> 
> Note 2
> 
> :
> 
> The other random
> number generation facilities in this document ([rand]) are often preferable
> to
> 
> rand
> 
> , because
> 
> rand
> 
> 's underlying algorithm is unspecified
> 
> .
> 
> Use of
> 
> rand
> 
> therefore continues to be non-portable, with unpredictable
> and oft-questionable quality and performance
> 
> .
> 
> —
> 
> end note
> 
> ]

See also:

ISO/IEC 9899:2018, 7.22.2

:::

:::wording

:::

### Feature test macros

#### Header <version> synopsis [version.syn]

```
#define __cpp_lib_constexpr_random 20????L          // also in <random> and <algorithm>
```
