14#ifndef RANGES_V3_VIEW_SAMPLE_HPP
15#define RANGES_V3_VIEW_SAMPLE_HPP
26#include <range/v3/utility/static_const.hpp>
31#include <range/v3/detail/prologue.hpp>
38 template<
typename Rng,
39 bool = (bool)sized_sentinel_for<sentinel_t<Rng>, iterator_t<Rng>>>
42 range_difference_t<Rng> size_;
45 CPP_assert(forward_range<Rng> || sized_range<Rng>);
46 size_tracker() =
default;
47 size_tracker(Rng & rng)
48 : size_(ranges::distance(rng))
54 range_difference_t<Rng> get(Rng &, iterator_t<Rng> &)
const
61 template<
typename Rng>
62 class size_tracker<Rng, true>
65 size_tracker() =
default;
70 range_difference_t<Rng> get(Rng & rng, iterator_t<Rng>
const & it)
const
72 return ranges::end(rng) - it;
82 template<
typename Rng,
typename URNG>
86 using D = range_difference_t<Rng>;
89 mutable range_difference_t<Rng> size_;
92 template<
bool IsConst>
95 friend cursor<!IsConst>;
97 using Base = meta::const_if_c<IsConst, Rng>;
98 meta::const_if_c<IsConst, sample_view> * parent_;
100 RANGES_NO_UNIQUE_ADDRESS detail::size_tracker<Base> size_;
104 return size_.get(parent_->rng_, current_);
108 if(parent_->size_ > 0)
110 using Dist = std::uniform_int_distribution<D>;
112 URNG & engine = *parent_->engine_;
114 for(;; ++current_, size_.decrement())
116 RANGES_ASSERT(current_ != ranges::end(parent_->rng_));
118 RANGES_EXPECT(n > 0);
119 typename Dist::param_type
const interval{0, n - 1};
120 if(dist(engine, interval) < parent_->size_)
127 using value_type = range_value_t<Rng>;
128 using difference_type = D;
131 explicit cursor(meta::const_if_c<IsConst, sample_view> * rng)
133 , current_(ranges::begin(rng->rng_))
141 template(
bool Other)(
142 requires IsConst AND CPP_NOT(Other))
143 cursor(cursor<Other> that)
144 : parent_(that.parent_)
145 , current_(std::move(that.current_))
148 range_reference_t<Rng> read()
const
154 RANGES_EXPECT(parent_);
155 return parent_->size_ <= 0;
159 RANGES_EXPECT(parent_);
160 RANGES_EXPECT(parent_->size_ > 0);
162 RANGES_ASSERT(current_ != ranges::end(parent_->rng_));
169 cursor<false> begin_cursor()
171 return cursor<false>{
this};
173 template(
bool Const =
true)(
179 cursor<Const> begin_cursor()
const
181 return cursor<true>{
this};
187 explicit sample_view(Rng rng, D sample_size, URNG & generator)
188 : rng_(std::move(rng))
190 , engine_(std::addressof(generator))
192 RANGES_EXPECT(sample_size >= 0);
201#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
202 template<
typename Rng,
typename URNG>
203 sample_view(Rng &&, range_difference_t<Rng>, URNG &)
204 ->sample_view<views::all_t<Rng>, URNG>;
212 template(
typename Rng,
typename URNG = detail::default_random_engine)(
215 convertible_to<invoke_result_t<URNG &>, range_difference_t<Rng>> AND
221 range_difference_t<Rng> sample_size,
222 URNG & generator = detail::get_random_engine())
const
225 all(
static_cast<Rng &&
>(rng)), sample_size, generator};
229 template<
typename Rng,
typename URNG>
230 invoke_result_t<sample_base_fn, Rng, range_difference_t<Rng>, URNG &>
233 range_difference_t<Rng> sample_size,
234 detail::reference_wrapper_<URNG> r)
const
236 return (*
this)(
static_cast<Rng &&
>(rng), sample_size, r.get());
243 using sample_base_fn::operator();
245 template(
typename Size,
typename URNG = detail::default_random_engine)(
247 constexpr auto operator()(
249 URNG & urng = detail::get_random_engine())
const
263#include <range/v3/detail/epilogue.hpp>
264#include <range/v3/detail/satisfy_boost_range.hpp>
Definition: sample.hpp:84
The forward_range concept.
The sized_sentinel_for concept.
The viewable_range concept.
decltype(begin(declval(Rng &))) iterator_t
Definition: access.hpp:698
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector > >, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
defer< bind_back, Fn, Ts... > bind_back
Definition: meta.hpp:994
Definition: default_sentinel.hpp:26
A utility for constructing a view from a (derived) type that implements begin and end cursors.
Definition: facade.hpp:66
Returns a random sample of a range of length size(range).
Definition: sample.hpp:211
Definition: sample.hpp:242