random-0.12.2/.gitignore01006000000765000002400000000024125672017260013257 0ustar0000000000000000/Cargo.lock /target random-0.12.2/.travis.yml01006000000765000002400000000141130056053340013367 0ustar0000000000000000language: rust sudo: false rust: - stable - beta - nightly notifications: email: false random-0.12.2/Cargo.toml01006000000765000002400000001532130056053760013221 0ustar0000000000000000# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "random" version = "0.12.2" authors = ["Ivan Ukhov "] description = "The package provides sources of randomness." homepage = "https://github.com/stainless-steel/random" documentation = "https://docs.rs/random" license = "Apache-2.0/MIT" repository = "https://github.com/stainless-steel/random" random-0.12.2/Cargo.toml.orig01006000000765000002400000000515130056053760014160 0ustar0000000000000000[package] name = "random" version = "0.12.2" license = "Apache-2.0/MIT" authors = ["Ivan Ukhov "] description = "The package provides sources of randomness." documentation = "https://docs.rs/random" homepage = "https://github.com/stainless-steel/random" repository = "https://github.com/stainless-steel/random" random-0.12.2/LICENSE.md01006440000765000002400000003765127163334620012721 0ustar0000000000000000# License The project is dual licensed under the terms of the Apache License, Version 2.0, and the MIT License. You may obtain copies of the two licenses at * https://www.apache.org/licenses/LICENSE-2.0 and * https://opensource.org/licenses/MIT, respectively. The following two notices apply to every file of the project. ## The Apache License ``` Copyright 2015, 2016 The random Developers Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` ## The MIT License ``` Copyright 2015, 2016 The random Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` random-0.12.2/README.md01006000000765000002400000001623130056053620012544 0ustar0000000000000000# Random [![Version][version-img]][version-url] [![Status][status-img]][status-url] The packages provides sources of randomness. ## [Documentation][documentation] ## Example ```rust use random::Source; let mut source = random::default().seed([42, 69]); println!("Scalar: {:?}", source.read::()); println!("Vector: {:?}", source.iter().take(2).collect::>()); ``` ## Contribution Your contribution is highly appreciated. Do not hesitate to open an issue or a pull request. Note that any contribution submitted for inclusion in the project will be licensed according to the terms given in [LICENSE.md](LICENSE.md). [documentation]: https://docs.rs/random [status-img]: https://travis-ci.org/stainless-steel/random.svg?branch=master [status-url]: https://travis-ci.org/stainless-steel/random [version-img]: https://img.shields.io/crates/v/random.svg [version-url]: https://crates.io/crates/random random-0.12.2/src/default.rs01006440000765000002400000002207127426374170014072 0ustar0000000000000000use std::cell::RefCell; use std::rc::Rc; use {Source, Xorshift128Plus}; /// An instance of the default source. /// /// The default source is the Xorshift128+ algorithm. #[derive(Clone)] pub struct Default(Rc>); impl Default { /// Create an instance of the default source. /// /// Each thread has its own copy of the default source, and each copy is /// initialized with the same default seed. Therefore, the usage is thread /// safe; however, each thread is responsible for reseeding its source. pub fn new() -> Default { thread_local!(static DEFAULT: Rc> = { Rc::new(RefCell::new(Xorshift128Plus::new([42, 69]))) }); Default(DEFAULT.with(|source| source.clone())) } /// Seed the source. /// /// At least one bit of the seed should be nonzero. #[inline(always)] pub fn seed(self, seed: [u64; 2]) -> Default { *self.0.borrow_mut() = Xorshift128Plus::new(seed); self } } impl Source for Default { #[inline(always)] fn read_u64(&mut self) -> u64 { self.0.borrow_mut().read_u64() } } random-0.12.2/src/lib.rs01006440000765000002400000001206127530355750013211 0ustar0000000000000000//! Sources of randomness. //! //! ## Example //! //! ``` //! use random::Source; //! //! let mut source = random::default().seed([42, 69]); //! println!("Scalar: {:?}", source.read::()); //! println!("Vector: {:?}", source.iter().take(2).collect::>()); //! ``` mod default; mod sequence; mod source; mod value; mod xorshift; pub use default::Default; pub use sequence::Sequence; pub use source::Source; pub use value::Value; pub use xorshift::Xorshift128Plus; /// Create an instance of the default source. /// /// For further information, see `Default::new`. #[inline(always)] pub fn default() -> Default { Default::new() } random-0.12.2/src/sequence.rs01006440000765000002400000001153127426374450014256 0ustar0000000000000000use std::marker::PhantomData; use {Source, Value}; /// A random sequence. pub struct Sequence<'l, S: ?Sized, V> where S: Source + 'l, V: Value + 'l { source: &'l mut S, phantom: PhantomData<&'l V>, } impl<'l, S, V> From<&'l mut S> for Sequence<'l, S, V> where S: Source, V: Value { #[inline(always)] fn from(source: &'l mut S) -> Self { Sequence { source: source, phantom: PhantomData } } } impl<'l, S, V> Iterator for Sequence<'l, S, V> where S: Source, V: Value { type Item = V; #[inline(always)] fn next(&mut self) -> Option { Some(self.source.read()) } } random-0.12.2/src/source.rs01006440000765000002400000001255127426374560013753 0ustar0000000000000000use {Sequence, Value}; /// A source of randomness. pub trait Source { /// Read `u64` uniformly distributed over `{0, 1, …, u64::MAX}`. fn read_u64(&mut self) -> u64; /// Read `f64` uniformly distributed over `[0, 1]`. #[inline(always)] fn read_f64(&mut self) -> f64 { self.read_u64() as f64 / ::std::u64::MAX as f64 } /// Read a random value. #[inline(always)] fn read(&mut self) -> V where Self: Sized, V: Value { Value::read(self) } /// Read a sequence of random values. #[inline(always)] fn iter<'l, V>(&'l mut self) -> Sequence<'l, Self, V> where Self: Sized, V: Value { From::from(self) } } random-0.12.2/src/value.rs01006440000765000002400000002165127426516640013565 0ustar0000000000000000use Source; /// A random value. pub trait Value { /// Read a random value. fn read(&mut S) -> Self where S: Source; } macro_rules! implement( ($reader:ident as $($kind:ty),*) => { $(impl Value for $kind { #[inline(always)] fn read(source: &mut S) -> Self where S: Source { source.$reader() as $kind } })* } ); implement!(read_f64 as f32, f64); implement!(read_u64 as i8, i16, i32, i64, isize); implement!(read_u64 as u8, u16, u32, u64, usize); #[cfg(test)] mod tests { use {Source, Value, Xorshift128Plus}; #[test] fn read() { let mut source = Xorshift128Plus::new([42, 69]); macro_rules! read( ($($kind:ident => [$one:expr, $two:expr],)*) => ({$( assert_eq!(source.read::<$kind>(), $one); assert_eq!($kind::read(&mut source), $two); )*}); ); read! { i8 => [52, -34], i16 => [-17348, -1036], i32 => [948125133, -1432682055], i64 => [-6330235019914458621, -4877218639256617945], } } } random-0.12.2/src/xorshift.rs01006000000765000002400000002141127426524560014301 0ustar0000000000000000use Source; /// An instance of the Xorshift128+ algorithm. /// /// ## References /// /// 1. Sebastiano Vigna, “Further Scramblings of Marsaglia’s Xorshift /// Generators,” CoRR, 2014. /// /// 2. https://en.wikipedia.org/wiki/Xorshift#xorshift.2B #[derive(Clone, Copy)] pub struct Xorshift128Plus(u64, u64); impl Xorshift128Plus { /// Create an instance of the algorithm. /// /// At least one bit of the seed should be one. #[inline(always)] pub fn new(seed: [u64; 2]) -> Xorshift128Plus { debug_assert!(seed[0] | seed[1] != 0, "at least one bit of the seed should be one"); Xorshift128Plus(seed[0], seed[1]) } } impl Source for Xorshift128Plus { #[inline(always)] fn read_u64(&mut self) -> u64 { let (mut x, y) = (self.0, self.1); self.0 = y; x = x ^ (x << 23); x = x ^ (x >> 17); x = x ^ y ^ (y >> 26); self.1 = x; x.wrapping_add(y) } } #[cfg(test)] mod tests { use Xorshift128Plus; #[test] #[should_panic] fn new_zero_seed() { let _ = Xorshift128Plus::new([0, 0]); } }