use super::*;
use crate::{Cmp, StringU8, TextLut, is};
impl Digits<usize> {
pub const MAX_DIGITS_10: u8 = Digits(usize::MAX).count_digits10();
pub const MAX_DIGITS_16: u8 = Digits(usize::MAX).count_digits16();
#[doc = DOC_COUNT_DIGITS_10!()]
#[must_use]
pub const fn count_digits10(self) -> u8 {
is![self.0 == 0, 1, self.0.ilog10() as u8 + 1]
}
#[doc = DOC_COUNT_DIGITS_16!()]
#[must_use]
pub const fn count_digits16(self) -> u8 {
is![self.0 == 0, 1, ((self.0.ilog2() + 4) / 4) as u8]
}
#[must_use]
#[inline(always)]
pub const fn digit_at_index10(self, index: u8) -> u8 {
is![index >= self.count_digits10(), return b'0'];
let power = TextLut::POWERS10[index as usize] as usize;
(self.0 / power % 10) as u8 + b'0'
}
#[must_use]
pub const fn digit_at_index10_checked(self, index: u8) -> Option<u8> {
is![index >= self.count_digits10(), return None];
let power = TextLut::POWERS10[index as usize] as usize;
Some((self.0 / power % 10) as u8 + b'0')
}
#[must_use]
pub const fn digit_at_index16(self, index: u8) -> u8 {
let shift = index as u32 * 4;
let digit = self.0.unbounded_shr(shift) & 0xF;
TextLut::DIGITS_BASE36[digit]
}
#[must_use]
pub const fn digit_at_index16_checked(self, index: u8) -> Option<u8> {
is![index >= self.count_digits16(), return None];
let shift = index as u32 * 4;
let digit = self.0.unbounded_shr(shift) & 0xF;
Some(TextLut::DIGITS_BASE36[digit])
}
#[must_use]
pub const fn digit_value_at_index10(self, index: u8) -> u8 {
is![index >= self.count_digits10(), return 0];
let power = TextLut::POWERS10[index as usize] as usize;
(self.0 / power % 10) as u8
}
#[must_use]
pub const fn digit_value_at_index10_checked(self, index: u8) -> Option<u8> {
is![index >= self.count_digits10(), return None];
let power = TextLut::POWERS10[index as usize] as usize;
Some((self.0 / power % 10) as u8)
}
#[must_use]
#[inline(always)]
pub const fn digit_value_at_index16(self, index: u8) -> u8 {
let shift = index as u32 * 4;
(self.0.unbounded_shr(shift) & 0xF) as u8
}
#[must_use]
pub const fn digit_value_at_index16_checked(self, index: u8) -> Option<u8> {
is![index < self.count_digits16(), Some(self.digit_value_at_index16(index)), None]
}
#[doc = DOC_DIGIT_AT_POWER_10!()]
#[must_use]
#[allow(dead_code)]
pub(crate) const fn digit_at_power10(self, divisor: usize) -> u8 {
(self.0 / divisor % 10) as u8 + b'0'
}
#[must_use]
#[cfg(target_pointer_width = "16")]
pub(crate) const fn digit_at_power16(self, divisor: usize) -> u8 {
Digits(self.0 as u16).digit_at_power16(divisor as u16)
}
#[must_use]
#[cfg(target_pointer_width = "32")]
pub(crate) const fn digit_at_power16(self, divisor: usize) -> u8 {
Digits(self.0 as u32).digit_at_power16(divisor as u32)
}
#[doc = DOC_DIGIT_AT_POWER_16!()]
#[must_use]
#[allow(dead_code)]
#[cfg(target_pointer_width = "64")]
pub(crate) const fn digit_at_power16(self, divisor: usize) -> u8 {
Digits(self.0 as u64).digit_at_power16(divisor as u64)
}
#[must_use]
#[cfg(target_pointer_width = "16")]
pub const fn digits10(self) -> [u8; Self::MAX_DIGITS_10 as usize] {
Digits(self.0 as u16).digits10()
}
#[must_use]
#[cfg(target_pointer_width = "16")]
pub const fn digits16(self) -> [u8; Self::MAX_DIGITS_16 as usize] {
Digits(self.0 as u16).digits16()
}
#[must_use]
#[cfg(target_pointer_width = "32")]
pub const fn digits10(self) -> [u8; Self::MAX_DIGITS_10 as usize] {
Digits(self.0 as u32).digits10()
}
#[must_use]
#[cfg(target_pointer_width = "32")]
pub const fn digits16(self) -> [u8; Self::MAX_DIGITS_16 as usize] {
Digits(self.0 as u32).digits16()
}
#[must_use]
#[cfg(target_pointer_width = "64")]
pub const fn digits10(self) -> [u8; Self::MAX_DIGITS_10 as usize] {
Digits(self.0 as u64).digits10()
}
#[must_use]
#[cfg(target_pointer_width = "64")]
pub const fn digits16(self) -> [u8; Self::MAX_DIGITS_16 as usize] {
Digits(self.0 as u64).digits16()
}
#[doc = DOC_WRITE_DIGITS_10!(10)]
#[must_use]
#[inline(always)]
#[cfg(target_pointer_width = "32")]
pub const fn write_digits10(self, buf: &mut [u8], offset: usize) -> usize {
Digits(self.0 as u32).write_digits10(buf, offset)
}
#[doc = DOC_WRITE_DIGITS_10_FAST!(10)]
#[must_use]
#[inline(always)]
#[cfg(target_pointer_width = "32")]
pub fn write_digits10_fast(self, buf: &mut [u8], offset: usize) -> usize {
Digits(self.0 as u32).write_digits10_fast(buf, offset)
}
#[doc = DOC_WRITE_DIGITS_10!(20)]
#[must_use]
#[inline(always)]
#[cfg(target_pointer_width = "64")]
pub const fn write_digits10(self, buf: &mut [u8], offset: usize) -> usize {
Digits(self.0 as u64).write_digits10(buf, offset)
}
#[doc = DOC_WRITE_DIGITS_10_FAST!(20)]
#[must_use]
#[inline(always)]
#[cfg(target_pointer_width = "64")]
pub fn write_digits10_fast(self, buf: &mut [u8], offset: usize) -> usize {
Digits(self.0 as u64).write_digits10_fast(buf, offset)
}
#[doc = DOC_DIGITS_STR!()] #[rustfmt::skip]
pub const fn digits10_str(self, width: u8) -> StringU8<{Self::MAX_DIGITS_10 as usize}> {
let width = Cmp(width).clamp(self.count_digits10(), Self::MAX_DIGITS_10);
#[cfg(any(feature = "safe_text", not(feature = "unsafe_str")))]
return crate::unwrap![ok StringU8::<{Self::MAX_DIGITS_10 as usize}>
::from_array_nright(self.digits10(), width)];
#[cfg(all(not(feature = "safe_text"), feature = "unsafe_str"))]
unsafe { StringU8::<{Self::MAX_DIGITS_10 as usize}>
::from_array_nright_unchecked(self.digits10(), width) }
}
#[doc = DOC_DIGITS_STR!()] #[rustfmt::skip]
pub const fn digits16_str(self, width: u8) -> StringU8<{Self::MAX_DIGITS_16 as usize}> {
let width = Cmp(width).clamp(self.count_digits16(), Self::MAX_DIGITS_16);
#[cfg(any(feature = "safe_text", not(feature = "unsafe_str")))]
return crate::unwrap![ok StringU8::<{Self::MAX_DIGITS_16 as usize}>
::from_array_nright(self.digits16(), width)];
#[cfg(all(not(feature = "safe_text"), feature = "unsafe_str"))]
unsafe { StringU8::<{Self::MAX_DIGITS_16 as usize}>
::from_array_nright_unchecked(self.digits16(), width) }
}
}