std::ranges::shuffle - cppreference.com

From cppreference.com

Defined in header

<algorithm>

Call signature

template<std::random_access_iteratorI,std::sentinel_for<I>S,classGen>requiresstd::permutable<I>&&std::uniform_random_bit_generator<std::remove_reference_t<Gen>>Ishuffle(Ifirst,Slast,Gen&&gen); (1) (since C++20)template<ranges::random_access_rangeR,classGen>requiresstd::permutable<ranges::iterator_t<R>>&&std::uniform_random_bit_generator<std::remove_reference_t<Gen>>ranges::borrowed_iterator_t<R>shuffle(R&&r,Gen&&gen); (2) (since C++20)Reorders the elements in the target range [first, last) or r such that each possible permutation of those elements has equal probability of appearance. The source of randomness is gen.

The function-like entities described on this page are

algorithm function objects

(informally known as niebloids), that is:

Explicit template argument lists cannot be specified when calling any of them.

None of them are visible to

argument-dependent lookup

.

When any of them are found by

normal unqualified lookup

as the name to the left of the function-call operator,

argument-dependent lookup

is inhibited.

Parameters

first, last - the iterator-sentinel pair defining the target

range

r - the target range gen - the random number generator Return value

The past the end iterator of the target range.

Complexity

Exactly (last-first)-1 swaps.

Possible implementation

structshuffle_fn{template<std::random_access_iteratorI,std::sentinel_for<I>S,classGen>requiresstd::permutable<I>&&std::uniform_random_bit_generator<std::remove_reference_t<Gen>>Ioperator()(Ifirst,Slast,Gen&&gen)const{usingdiff_t=std::iter_difference_t<I>;usingdistr_t=std::uniform_int_distribution<diff_t>;usingparam_t=typenamedistr_t::param_type;distr_tD;constauton{last-first};for(diff_ti{1};i<n;++i)ranges::iter_swap(first+i,first+D(gen,param_t(0,i)));returnranges::next(first,last);}template<ranges::random_access_rangeR,classGen>requiresstd::permutable<ranges::iterator_t<R>>&&std::uniform_random_bit_generator<std::remove_reference_t<Gen>>ranges::borrowed_iterator_t<R>operator()(R&&r,Gen&&gen)const{return(*this)(ranges::begin(r),ranges::next(ranges::begin(r),ranges::end(r)),std::forward<Gen>(gen));}};inlineconstexprshuffle_fnshuffle{};Example

Run this code

#include<algorithm>#include<array>#include<print>#include<random>intmain(){std::arraya{'A','B','C','D','E','F'};std::println("{:n:}",a);std::random_devicerd;std::mt19937gen{rd()};for(inti{};i!=3;++i){std::ranges::shuffle(a,gen);std::println("{:n:}",a);}}Possible output:

A, B, C, D, E, F A, E, F, B, D, C E, F, D, A, C, B A, F, C, E, D, B See also