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);
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());