Skip to content

Commit 284e9e4

Browse files
committed
Various build and comment fixes.
1 parent 08f6f7b commit 284e9e4

File tree

1 file changed

+55
-34
lines changed

1 file changed

+55
-34
lines changed

src/seq.rs

+55-34
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
use super::Rng;
2525
use distributions::uniform::{SampleUniform, SampleBorrow};
26+
#[cfg(feature = "alloc")]
2627
use distributions::Distribution;
2728

2829
/// Extension trait on slices, providing random mutation and sampling methods.
@@ -102,9 +103,9 @@ pub trait SliceRandom {
102103
///
103104
/// ```
104105
/// use rand::prelude::*;
105-
/// //use rand::distributions::uniform::SampleBorrow;
106106
///
107107
/// let choices = [('a', 2), ('b', 1), ('c', 1)];
108+
/// // In rustc version XXX and newer, you can use a closure instead
108109
/// fn mapping_func(item: &(char, usize)) -> usize {
109110
/// item.1
110111
/// }
@@ -126,22 +127,10 @@ pub trait SliceRandom {
126127
/// likelyhood of getting returned. The likelyhood of a given item getting
127128
/// returned is proportional to the value returned by the mapping function
128129
/// `func`.
129-
///
130-
/// # Example
131-
///
132-
/// ```
133-
/// use rand::prelude::*;
134-
/// //use rand::distributions::uniform::SampleBorrow;
135130
///
136-
/// let choices = [('a', 2), ('b', 1), ('c', 1)];
137-
/// fn mapping_func(item: &(char, usize)) -> usize {
138-
/// item.1
139-
/// }
140-
/// let mut rng = thread_rng();
141-
/// // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
142-
/// println!("{:?}", choices.choose_weighted(&mut rng, &mapping_func).unwrap().0);
143-
/// ```
131+
/// See also [`choose_weighted`].
144132
/// [`choose_mut`]: trait.SliceRandom.html#method.choose_mut
133+
/// [`choose_weighted`]: trait.SliceRandom.html#method.choose_weighted
145134
fn choose_weighted_mut<R, F, B, X>(&mut self, rng: &mut R, func: F) -> Option<&mut Self::Item>
146135
where R: Rng + ?Sized,
147136
F: Fn(&Self::Item) -> B + Clone,
@@ -296,18 +285,23 @@ pub trait IteratorRandom: Iterator + Sized {
296285
}
297286
}
298287

299-
/// Extension trait on iterators, providing random sampling methods.
288+
/// Extension trait on IntoIterator, providing random sampling methods.
300289
pub trait IntoIteratorRandom: IntoIterator + Sized {
301290

302291
/// Return a the index of a random element from this iterator where the
303292
/// chance of a given item being picked is proportional to the value of
304293
/// the item.
305294
///
295+
/// If calling this on a [`Vec`], make sure to use
296+
/// `(&vec).choose_index_weighted(...)`. Otherwise the [`Vec`] and all of
297+
/// its contents will be cloned.
298+
///
306299
/// All values returned by the iterator must be `>= 0`.
307300
///
308301
/// This function iterates over the iterator twice. Once to get the total
309-
/// weight, and once while choosing the random item. If you plan to call
310-
/// this function multiple times, it would be more performant to use
302+
/// weight, and once while choosing the random item. This is done by
303+
/// cloning the iterator. If you plan to call this function multiple times,
304+
/// it would be more performant to use
311305
/// [`into_weighted_index_distribution`].
312306
///
313307
/// Return `None` if self is empty, or contains only `0`s.
@@ -328,6 +322,7 @@ pub trait IntoIteratorRandom: IntoIterator + Sized {
328322
/// println!("{}", weights.choose_index_weighted(&mut rng).map(|ix| choices[ix]).unwrap());
329323
/// ```
330324
/// [`into_weighted_index_distribution`]: trait.IntoIteratorRandom.html#method.into_weighted_index_distribution
325+
/// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
331326
fn choose_index_weighted<R, X>(self, rng: &mut R) -> Option<usize>
332327
where Self::IntoIter: Clone,
333328
R: Rng + ?Sized,
@@ -361,9 +356,9 @@ pub trait IntoIteratorRandom: IntoIterator + Sized {
361356
panic!("Weights changed during cloning");
362357
}
363358

364-
/// Returns a [`Distribution`] which when sampled from, returns a random
365-
/// element from this iterator where the chance of a given item being
366-
/// picked is proportional to the value of the item.
359+
/// Returns a [`Distribution`] which when sampled from, returns the index
360+
/// of a random element from this iterator where the chance of a given
361+
/// item being picked is proportional to the value of the item.
367362
///
368363
/// # Panics
369364
///
@@ -454,6 +449,10 @@ impl<T> SliceRandom for [T] {
454449
for<'a> ::core::ops::AddAssign<&'a X> +
455450
::core::cmp::PartialOrd<X> +
456451
Default {
452+
// Technically we could move choose_weighted to IntoIteratorRandom.
453+
// That does carry the small risk that someone will do something silly like:
454+
// my_vec.clone().choose_weighted(&mut r, |item| ...)
455+
// which would clone the vector and its contents 3 times.
457456
self.iter().map(func).choose_index_weighted(rng).map(|ix| &self[ix])
458457
}
459458

@@ -465,6 +464,10 @@ impl<T> SliceRandom for [T] {
465464
for<'a> ::core::ops::AddAssign<&'a X> +
466465
::core::cmp::PartialOrd<X> +
467466
Default {
467+
// Technically we could move choose_weighted_mut to IntoIteratorRandom.
468+
// That does carry the small risk that someone will do something silly like:
469+
// my_vec.clone().choose_weighted(&mut r, |item| ...)
470+
// which would clone the vector and its contents 3 times.
468471
let index = self.iter().map(func).choose_index_weighted(rng);
469472
index.map(move |ix| &mut self[ix])
470473
}
@@ -925,15 +928,15 @@ mod test {
925928
}
926929
};
927930

928-
// choose_weighted array
931+
// choose_index_weighted array
929932
let mut chosen = [0i32; 14];
930933
for _ in 0..1000 {
931934
let picked = weights.choose_index_weighted(&mut r).unwrap();
932935
chosen[picked] += 1;
933936
}
934937
verify(chosen);
935938

936-
// choose_weighted ref iterator
939+
// choose_index_weighted ref iterator
937940
chosen = [0i32; 14];
938941
for _ in 0..1000 {
939942
let picked = weights.iter()
@@ -942,7 +945,7 @@ mod test {
942945
}
943946
verify(chosen);
944947

945-
// choose_weighted value iterator
948+
// choose_index_weighted value iterator
946949
chosen = [0i32; 14];
947950
for _ in 0..1000 {
948951
let picked = weights.iter()
@@ -952,33 +955,51 @@ mod test {
952955
}
953956
verify(chosen);
954957

955-
// choose_weighted value iterator
956-
chosen = [0i32; 14];
957-
let distr = weights.into_weighted_index_distribution();
958-
for _ in 0..1000 {
959-
chosen[distr.sample(&mut r)] += 1;
958+
// choose_index_weighted Vec<...>
959+
#[cfg(feature = "alloc")]
960+
{
961+
chosen = [0i32; 14];
962+
let vec_weights = weights.to_vec();
963+
for _ in 0..1000 {
964+
let picked = (&vec_weights).choose_index_weighted(&mut r).unwrap();
965+
chosen[picked] += 1;
966+
}
967+
verify(chosen);
968+
}
969+
970+
// into_weighted_index_distribution
971+
#[cfg(feature = "alloc")]
972+
{
973+
chosen = [0i32; 14];
974+
let distr = weights.into_weighted_index_distribution();
975+
for _ in 0..1000 {
976+
chosen[distr.sample(&mut r)] += 1;
977+
}
978+
verify(chosen);
960979
}
961-
verify(chosen);
962980

963981
// choose_weighted
982+
fn get_weight<T>(item: &(u32, T)) -> u32 {
983+
item.0
984+
}
964985
chosen = [0i32; 14];
965-
let mut items = [(0u32, 0usize); 14];
986+
let mut items = [(0u32, 0usize); 14]; // (weight, index)
966987
for (i, item) in items.iter_mut().enumerate() {
967988
*item = (weights[i], i);
968989
}
969990
for _ in 0..1000 {
970-
let item = items.choose_weighted(&mut r, |item| item.0).unwrap();
991+
let item = items.choose_weighted(&mut r, get_weight).unwrap();
971992
chosen[item.1] += 1;
972993
}
973994
verify(chosen);
974995

975996
// choose_weighted_mut
976-
let mut items = [(0u32, 0i32); 14];
997+
let mut items = [(0u32, 0i32); 14]; // (weight, count)
977998
for (i, item) in items.iter_mut().enumerate() {
978999
*item = (weights[i], 0);
9791000
}
9801001
for _ in 0..1000 {
981-
items.choose_weighted_mut(&mut r, |item| item.0).unwrap().1 += 1;
1002+
items.choose_weighted_mut(&mut r, get_weight).unwrap().1 += 1;
9821003
}
9831004
for (ch, item) in chosen.iter_mut().zip(items.iter()) {
9841005
*ch = item.1;

0 commit comments

Comments
 (0)