14#ifndef RANGES_V3_ALGORITHM_SAMPLE_HPP
15#define RANGES_V3_ALGORITHM_SAMPLE_HPP
30#include <range/v3/utility/static_const.hpp>
32#include <range/v3/detail/prologue.hpp>
38 template<
typename I,
typename O>
39 using sample_result = detail::in_out_result<I, O>;
44 template<
typename I,
typename S,
typename O,
typename Gen>
45 sample_result<I, O> sample_sized_impl(I first,
47 iter_difference_t<I> pop_size,
49 iter_difference_t<O> sample_size,
52 if(pop_size > 0 && sample_size > 0)
54 std::uniform_int_distribution<iter_difference_t<I>> dist;
55 using param_t =
typename decltype(dist)::param_type;
58 if(sample_size >= pop_size)
59 return copy_n(std::move(first), pop_size, std::move(out));
61 if(dist(gen, param_t{0, --pop_size}) < sample_size)
65 if(--sample_size == 0)
71 return {std::move(first), std::move(out)};
76 RANGES_FUNC_BEGIN(sample)
82 typename Gen = detail::default_random_engine &)(
88 sample_result<I, O> RANGES_FUNC(sample)(I first,
91 iter_difference_t<O> const n,
92 Gen && gen = detail::get_random_engine())
96 auto const k = distance(first, last);
97 return detail::sample_sized_impl(std::move(first),
102 static_cast<Gen &&
>(gen));
110 for(iter_difference_t<O> i = 0; i < n; (void)++i, ++first)
117 *next(out, i) = *first;
120 std::uniform_int_distribution<iter_difference_t<O>> dist;
121 using param_t =
typename decltype(dist)::param_type;
122 for(
auto pop_size = n; first != last; (void)++first, ++pop_size)
124 auto const i = dist(gen, param_t{0, pop_size});
126 *next(out, i) = *first;
132 return {std::move(first), std::move(out)};
140 typename Gen = detail::default_random_engine &)(
148 sample_result<I, borrowed_iterator_t<ORng>> RANGES_FUNC(sample)(
152 Gen && gen = detail::get_random_engine())
156 auto k = distance(first, last);
157 return detail::sample_sized_impl(std::move(first),
162 static_cast<Gen &&
>(gen));
166 return (*
this)(std::move(first),
170 static_cast<Gen &&
>(gen));
175 template(
typename Rng,
177 typename Gen = detail::default_random_engine &)(
182 sample_result<borrowed_iterator_t<Rng>, O> RANGES_FUNC(sample)(
185 iter_difference_t<O>
const n,
186 Gen && gen = detail::get_random_engine())
190 return detail::sample_sized_impl(begin(rng),
195 static_cast<Gen &&
>(gen));
200 begin(rng), end(rng), std::move(out), n,
static_cast<Gen &&
>(gen));
205 template(
typename IRng,
207 typename Gen = detail::default_random_engine &)(
214 sample_result<borrowed_iterator_t<IRng>, borrowed_iterator_t<ORng>>
215 RANGES_FUNC(sample)(IRng && rng,
217 Gen && gen = detail::get_random_engine())
221 return detail::sample_sized_impl(begin(rng),
226 static_cast<Gen &&
>(gen));
230 return (*
this)(begin(rng),
234 static_cast<Gen &&
>(gen));
238 RANGES_FUNC_END(sample)
242 using ranges::sample_result;
243 using ranges::sample;
248#include <range/v3/detail/epilogue.hpp>
The forward_iterator concept.
The forward_range concept.
The indirectly_copyable concept.
The random_access_iterator concept.
The sentinel_for concept.
The sized_sentinel_for concept.
The weakly_incrementable concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
front< Pair > first
Retrieve the first element of the pair Pair.
Definition meta.hpp:2251