#[cfg(test)]
mod tests;
use core::num::{NonZeroI128, NonZeroU128};
use core::num::{NonZeroI16, NonZeroU16};
use core::num::{NonZeroI32, NonZeroU32};
use core::num::{NonZeroI64, NonZeroU64};
use core::num::{NonZeroI8, NonZeroU8};
use core::num::{NonZeroIsize, NonZeroUsize};
use std::fmt::{Display, Formatter, Result};
use std::iter::successors;
#[derive(Debug, Clone, Copy)]
pub struct Radix<T> {
n: T,
base: u8,
}
impl<T> Radix<T>
where
Radix<T>: Display,
{
pub fn new(n: T, base: u8) -> Self {
assert!(base >= 2 && base <= 36);
Radix { n, base }
}
}
#[inline(always)]
fn digit(u: u8, alternate: bool) -> u8 {
let a = if alternate { b'A' } else { b'a' };
match u {
0...9 => u + b'0',
10...35 => u - 10 + a,
_ => unreachable!("Digit is not in range [0..36]"),
}
}
const BUF_SIZE: usize = 81;
macro_rules! impl_display_for {
($i: ty => $via: ty as $u: ty) => {
impl Display for Radix<$i> {
fn fmt(&self, f: &mut Formatter) -> Result {
fn do_format(n: $u, base: $u, f: &mut Formatter) -> Result {
let mut buffer = [0_u8; BUF_SIZE];
let divided = successors(Some(n), |n| match n / base {
0 => None,
n => Some(n),
});
let written = buffer
.iter_mut()
.rev()
.zip(divided)
.map(|(c, n)| *c = digit((n % base) as u8, f.alternate()))
.count();
let index = BUF_SIZE - written;
let s = unsafe { std::str::from_utf8_unchecked(&buffer[index..]) };
f.write_str(s)
}
match (self.base, f.alternate()) {
(2, _) => write!(f, "{:b}", self.n),
(8, _) => write!(f, "{:o}", self.n),
(10, _) => write!(f, "{}", self.n),
(16, false) => write!(f, "{:x}", self.n),
(16, true) => write!(f, "{:X}", self.n),
(base, _) => do_format(<$via>::from(self.n) as $u, base.into(), f),
}
}
}
};
}
impl_display_for!(i8 => i8 as u8);
impl_display_for!(u8 => u8 as u8);
impl_display_for!(i16 => i16 as u16);
impl_display_for!(u16 => u16 as u16);
impl_display_for!(i32 => i32 as u32);
impl_display_for!(u32 => u32 as u32);
impl_display_for!(i64 => i64 as u64);
impl_display_for!(u64 => u64 as u64);
impl_display_for!(i128 => i128 as u128);
impl_display_for!(u128 => u128 as u128);
impl_display_for!(isize => isize as usize);
impl_display_for!(usize => usize as usize);
impl_display_for!(NonZeroI8 => i8 as u8);
impl_display_for!(NonZeroU8 => u8 as u8);
impl_display_for!(NonZeroI16 => i16 as u16);
impl_display_for!(NonZeroU16 => u16 as u16);
impl_display_for!(NonZeroI32 => i32 as u32);
impl_display_for!(NonZeroU32 => u32 as u32);
impl_display_for!(NonZeroI64 => i64 as u64);
impl_display_for!(NonZeroU64 => u64 as u64);
impl_display_for!(NonZeroI128 => i128 as u128);
impl_display_for!(NonZeroU128 => u128 as u128);
impl_display_for!(NonZeroIsize => isize as usize);
impl_display_for!(NonZeroUsize => usize as usize);
pub fn radix<T>(n: T, base: u8) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, base)
}
pub fn radix_3<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 3)
}
pub fn radix_4<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 4)
}
pub fn radix_5<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 5)
}
pub fn radix_6<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 6)
}
pub fn radix_7<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 7)
}
pub fn radix_9<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 9)
}
pub fn radix_11<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 11)
}
pub fn radix_12<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 12)
}
pub fn radix_13<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 13)
}
pub fn radix_14<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 14)
}
pub fn radix_15<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 15)
}
pub fn radix_17<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 17)
}
pub fn radix_18<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 18)
}
pub fn radix_19<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 19)
}
pub fn radix_20<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 20)
}
pub fn radix_21<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 21)
}
pub fn radix_22<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 22)
}
pub fn radix_23<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 23)
}
pub fn radix_24<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 24)
}
pub fn radix_25<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 25)
}
pub fn radix_26<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 26)
}
pub fn radix_27<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 27)
}
pub fn radix_28<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 28)
}
pub fn radix_29<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 29)
}
pub fn radix_30<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 30)
}
pub fn radix_31<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 31)
}
pub fn radix_32<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 32)
}
pub fn radix_33<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 33)
}
pub fn radix_34<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 34)
}
pub fn radix_35<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 35)
}
pub fn radix_36<T>(n: T) -> Radix<T>
where
Radix<T>: Display,
{
Radix::new(n, 36)
}