Last active
December 1, 2017 16:45
-
-
Save nvzqz/49c32c8585108afae51e9642c6872f68 to your computer and use it in GitHub Desktop.
`Choose` trait for rand crate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(specialization)] | |
extern crate rand; | |
use rand::Rng; | |
trait Choose { | |
type Item; | |
fn choose<R: Rng>(self, rng: &mut R) -> Option<Self::Item>; | |
} | |
impl<T: IntoIterator> Choose for T { | |
type Item = <T as IntoIterator>::Item; | |
default fn choose<R: Rng>(self, rng: &mut R) -> Option<T::Item> { | |
let mut value = None; | |
for (i, elem) in self.into_iter().enumerate() { | |
if i == 0 || rng.gen_range(0, i + 1) == 0 { | |
value = Some(elem); | |
} | |
} | |
value | |
} | |
} | |
impl<'a, T> Choose for &'a [T] { | |
fn choose<R: Rng>(self, rng: &mut R) -> Option<&'a T> { | |
if self.is_empty() { | |
None | |
} else { | |
Some(&self[rng.gen_range(0, self.len())]) | |
} | |
} | |
} | |
impl<'a, T> Choose for &'a mut [T] { | |
fn choose<R: Rng>(self, rng: &mut R) -> Option<&'a mut T> { | |
if self.is_empty() { | |
None | |
} else { | |
let len = self.len(); | |
Some(&mut self[rng.gen_range(0, len)]) | |
} | |
} | |
} | |
fn main() { | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment