use crate::{DiceExt, DiceExtSides};
use super::InclusiveRandomRange;
impl InclusiveRandomRange<i32> for std::ops::RangeInclusive<i32> {
fn random_of(&self) -> i32 {
let (mut start, mut end) = (*self.start(), *self.end());
if start > end {
std::mem::swap(&mut start, &mut end);
}
let start = start as i64;
let end = end as i64;
let sides = end - start + 1;
(start + (1.d(sides as u64 as DiceExtSides) - 1) as i64) as i32
}
}
#[cfg(feature = "f128-stable")]
impl InclusiveRandomRange<f128> for std::ops::RangeInclusive<f64> {
fn random_of(&self) -> f128 {
let (mut start, mut end) = (*self.start(), *self.end());
if start > end { std::mem::swap(&mut start, &mut end); }
let raw_bits = engine::GLOBAL_REACTOR_U128.roll(u128::MAX); let max_m = (1u128 << 113) - 1; start + ((raw_bits & max_m) as f128 / max_m as f128) * (end - start)
}
}
impl InclusiveRandomRange<f64> for std::ops::RangeInclusive<f64> {
fn random_of(&self) -> f64 {
let (mut start, mut end) = (*self.start(), *self.end());
if start > end { std::mem::swap(&mut start, &mut end); }
let raw_bits = 1.d(u64::MAX as DiceExtSides);
let max_m = (1u64 << 53) - 1; start + ((raw_bits & max_m) as f64 / max_m as f64) * (end - start)
}
}
impl InclusiveRandomRange<f32> for std::ops::RangeInclusive<f32> {
fn random_of(&self) -> f32 {
let (mut start, mut end) = (*self.start(), *self.end());
if start > end { std::mem::swap(&mut start, &mut end); }
let raw_bits = 1.d(u64::MAX as DiceExtSides);
let max_m = (1u32 << 24) - 1; start + ((raw_bits as u32 & max_m) as f32 / max_m as f32) * (end - start)
}
}
impl InclusiveRandomRange<char> for std::ops::RangeInclusive<char> {
fn random_of(&self) -> char {
let (mut start, mut end) = (*self.start(), *self.end());
if start > end { std::mem::swap(&mut start, &mut end); }
let u_start = start as u32;
let u_end = end as u32;
let range = u_end - u_start + 1;
loop {
let offt = 1.d(range as u64 as DiceExtSides) as u32;
let maybe = u_start + offt;
if !(0xD800..=0xDFFF).contains(&maybe) {
return unsafe { char::from_u32_unchecked(maybe) }
}
}
}
}