Skip to main content

dashu_int/third_party/
rand_v010.rs

1use crate::{
2    arch::word::{DoubleWord, Word},
3    ibig::IBig,
4    ops::UnsignedAbs,
5    ubig::UBig,
6};
7use rand_v010::{
8    distr::uniform::{Error, SampleBorrow, SampleUniform, UniformSampler},
9    distr::Distribution,
10    Rng, RngExt,
11};
12
13use super::rand::*;
14
15/// Adapter exposing a rand 0.10 [`Rng`] as a [`BitRng`].
16pub struct RngBridge<'a, R: Rng + ?Sized>(pub &'a mut R);
17
18impl<'a, R: Rng + ?Sized> BitRng for RngBridge<'a, R> {
19    #[inline]
20    fn next_word(&mut self) -> Word {
21        self.0.random()
22    }
23    #[inline]
24    fn next_double_word(&mut self) -> DoubleWord {
25        self.0.random()
26    }
27    #[inline]
28    fn next_bool(&mut self) -> bool {
29        self.0.random()
30    }
31    #[inline]
32    fn fill_words(&mut self, words: &mut [Word]) {
33        self.0.fill(words)
34    }
35    #[inline]
36    fn gen_word_inclusive(&mut self, high: Word) -> Word {
37        self.0.random_range(0..=high)
38    }
39    #[inline]
40    fn gen_dword_exclusive(&mut self, high: DoubleWord) -> DoubleWord {
41        self.0.random_range(0..high)
42    }
43}
44
45fn bridge<R: Rng + ?Sized>(rng: &mut R) -> RngBridge<'_, R> {
46    RngBridge(rng)
47}
48
49impl Distribution<UBig> for UniformBits {
50    #[inline]
51    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> UBig {
52        self.sample_ubig(&mut bridge(rng))
53    }
54}
55
56impl Distribution<IBig> for UniformBits {
57    #[inline]
58    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> IBig {
59        self.sample_ibig(&mut bridge(rng))
60    }
61}
62
63impl Distribution<UBig> for UniformBelow<'_> {
64    #[inline]
65    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> UBig {
66        self.sample_ubig(&mut bridge(rng))
67    }
68}
69
70impl Distribution<IBig> for UniformBelow<'_> {
71    #[inline]
72    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> IBig {
73        self.sample_ibig(&mut bridge(rng))
74    }
75}
76
77impl UniformSampler for UniformUBig {
78    type X = UBig;
79
80    #[inline]
81    fn new<B1, B2>(low: B1, high: B2) -> Result<UniformUBig, Error>
82    where
83        B1: SampleBorrow<UBig> + Sized,
84        B2: SampleBorrow<UBig> + Sized,
85    {
86        if high.borrow() <= low.borrow() {
87            return Err(Error::EmptyRange);
88        }
89        let range = high.borrow() - low.borrow();
90        Ok(UniformUBig::from_parts(range, low.borrow().clone()))
91    }
92
93    #[inline]
94    fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<UniformUBig, Error>
95    where
96        B1: SampleBorrow<UBig> + Sized,
97        B2: SampleBorrow<UBig> + Sized,
98    {
99        if high.borrow() < low.borrow() {
100            return Err(Error::EmptyRange);
101        }
102        let range = high.borrow() - low.borrow() + UBig::ONE;
103        Ok(UniformUBig::from_parts(range, low.borrow().clone()))
104    }
105
106    #[inline]
107    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> UBig {
108        let mut b = bridge(rng);
109        UniformUBig::sample(self, &mut b)
110    }
111}
112
113impl UniformSampler for UniformIBig {
114    type X = IBig;
115
116    #[inline]
117    fn new<B1, B2>(low: B1, high: B2) -> Result<UniformIBig, Error>
118    where
119        B1: SampleBorrow<IBig> + Sized,
120        B2: SampleBorrow<IBig> + Sized,
121    {
122        if high.borrow() <= low.borrow() {
123            return Err(Error::EmptyRange);
124        }
125        let range = high.borrow() - low.borrow();
126        Ok(UniformIBig::from_parts(range.unsigned_abs(), low.borrow().clone()))
127    }
128
129    #[inline]
130    fn new_inclusive<B1, B2>(low: B1, high: B2) -> Result<UniformIBig, Error>
131    where
132        B1: SampleBorrow<IBig> + Sized,
133        B2: SampleBorrow<IBig> + Sized,
134    {
135        if high.borrow() < low.borrow() {
136            return Err(Error::EmptyRange);
137        }
138        let range = high.borrow() - low.borrow() + IBig::ONE;
139        Ok(UniformIBig::from_parts(range.unsigned_abs(), low.borrow().clone()))
140    }
141
142    #[inline]
143    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> IBig {
144        let mut b = bridge(rng);
145        UniformIBig::sample(self, &mut b)
146    }
147}
148
149impl SampleUniform for UBig {
150    type Sampler = UniformUBig;
151}
152
153impl SampleUniform for IBig {
154    type Sampler = UniformIBig;
155}