|
9 | 9 | use core::num::NonZeroUsize; |
10 | 10 |
|
11 | 11 | use crate::distributions::{Distribution, Uniform}; |
12 | | -#[cfg(feature = "alloc")] |
13 | | -use alloc::string::String; |
| 12 | +#[cfg(feature = "alloc")] use alloc::string::String; |
14 | 13 |
|
15 | 14 | /// A distribution to sample items uniformly from a slice. |
16 | 15 | /// |
@@ -69,26 +68,28 @@ use alloc::string::String; |
69 | 68 | pub struct Slice<'a, T> { |
70 | 69 | slice: &'a [T], |
71 | 70 | range: Uniform<usize>, |
| 71 | + choices: NonZeroUsize, |
72 | 72 | } |
73 | 73 |
|
74 | 74 | impl<'a, T> Slice<'a, T> { |
75 | 75 | /// Create a new `Slice` instance which samples uniformly from the slice. |
76 | 76 | /// Returns `Err` if the slice is empty. |
77 | 77 | pub fn new(slice: &'a [T]) -> Result<Self, EmptySlice> { |
78 | | - match slice.len() { |
79 | | - 0 => Err(EmptySlice), |
80 | | - len => Ok(Self { |
81 | | - slice, |
82 | | - range: Uniform::new(0, len).unwrap(), |
83 | | - }), |
84 | | - } |
| 78 | + let len = match NonZeroUsize::new(slice.len()) { |
| 79 | + None => return Err(EmptySlice), |
| 80 | + Some(len) => len, |
| 81 | + }; |
| 82 | + |
| 83 | + Ok(Self { |
| 84 | + slice, |
| 85 | + range: Uniform::new(0, len).unwrap(), |
| 86 | + choices: len, |
| 87 | + }) |
85 | 88 | } |
86 | 89 |
|
87 | 90 | /// Returns the count of choices in this distribution |
88 | 91 | pub fn num_choices(&self) -> NonZeroUsize { |
89 | | - // Safety: at construction time, it was ensured that the slice was |
90 | | - // non-empty, as such the length can never be 0. |
91 | | - unsafe { NonZeroUsize::new_unchecked(self.slice.len()) } |
| 92 | + self.choices |
92 | 93 | } |
93 | 94 | } |
94 | 95 |
|
@@ -148,7 +149,11 @@ impl<'a> super::DistString for Slice<'a, char> { |
148 | 149 |
|
149 | 150 | // Split the extension of string to reuse the unused capacities. |
150 | 151 | // Skip the split for small length or only ascii slice. |
151 | | - let mut extend_len = if max_char_len == 1 || len < 100 { len } else { len / 4 }; |
| 152 | + let mut extend_len = if max_char_len == 1 || len < 100 { |
| 153 | + len |
| 154 | + } else { |
| 155 | + len / 4 |
| 156 | + }; |
152 | 157 | let mut remain_len = len; |
153 | 158 | while extend_len > 0 { |
154 | 159 | string.reserve(max_char_len * extend_len); |
|
0 commit comments