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())
94 if(RANGES_CONSTEXPR_IF(forward_iterator<I> || sized_sentinel_for<S, I>))
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 &)(
141 requires input_iterator<I> AND sentinel_for<S, I> AND
145 (forward_range<ORng> || sized_range<ORng>) AND
147 sized_sentinel_for<S, I>))
148 sample_result<I, borrowed_iterator_t<ORng>> RANGES_FUNC(sample)(
152 Gen && gen = detail::get_random_engine())
154 if(RANGES_CONSTEXPR_IF(forward_iterator<I> || sized_sentinel_for<S, I>))
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 &)(
178 requires input_range<Rng> AND weakly_incrementable<O> AND
181 (random_access_iterator<O> || forward_range<Rng> || sized_range<Rng>))
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())
188 if(RANGES_CONSTEXPR_IF(forward_range<Rng> || sized_range<Rng>))
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 &)(
208 requires input_range<IRng> AND range<ORng> AND
212 sized_range<IRng>) AND
213 (forward_range<ORng> || sized_range<ORng>))
214 sample_result<borrowed_iterator_t<IRng>, borrowed_iterator_t<ORng>>
215 RANGES_FUNC(sample)(IRng && rng,
217 Gen && gen = detail::get_random_engine())
219 if(RANGES_CONSTEXPR_IF(forward_range<IRng> || sized_range<IRng>))
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>
template(typename IRng, typename ORng, typename Gen=detail::default_random_engine &)(requires input_range< IRng > AND range< ORng > AND indirectly_copyable< iterator_t< IRng >
This is an overloaded member function, provided for convenience. It differs from the above function o...
CPP_concept sentinel_for
\concept sentinel_for
Definition: concepts.hpp:306
CPP_concept input_iterator
\concept input_iterator
Definition: concepts.hpp:362
CPP_concept sized_sentinel_for
\concept sized_sentinel_for
Definition: concepts.hpp:332
CPP_concept forward_iterator
\concept forward_iterator
Definition: concepts.hpp:370
CPP_concept random_access_iterator
\concept random_access_iterator
Definition: concepts.hpp:416
CPP_concept indirectly_copyable
\concept indirectly_copyable
Definition: concepts.hpp:782
CPP_concept weakly_incrementable
\concept weakly_incrementable
Definition: concepts.hpp:268
CPP_concept uniform_random_bit_generator
\concept uniform_random_bit_generator
Definition: random.hpp:99
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