//! Radix-generic, lexical integer-to-string conversion routines.
//!
//! These routines are decently optimized: they unroll 4 loops at a time,
//! using pre-computed base^2 tables. However, due to static storage
//! reasons, it makes no sense to pre-compute the number of digits,
//! and therefore
//!
//! See [Algorithm](/docs/Algorithm.md) for a more detailed description of
//! the algorithm choice here.
#![cfg(not(feature = "compact"))]
#![cfg(feature = "power-of-two")]
#![doc(hidden)]
use lexical_util::format;
use lexical_util::num::{Integer, UnsignedInteger};
use crate::algorithm::{algorithm, algorithm_u128};
use crate::table::get_table;
/// Write integer to radix string.
pub trait Radix: UnsignedInteger {
/// # Safety
///
/// Safe as long as buffer is at least `FORMATTED_SIZE` elements long,
/// (or `FORMATTED_SIZE_DECIMAL` for decimal), and the radix is valid.
fn radix<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
self,
buffer: &mut [u8],
) -> usize;
}
// Implement radix for type.
macro_rules! radix_impl {
($($t:ty)*) => ($(
impl Radix for $t {
#[inline(always)]
fn radix<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
self,
buffer: &mut [u8]
) -> usize {
debug_assert!(<Self as Integer>::BITS <= 64);
let radix = format::radix_from_flags(FORMAT, MASK, SHIFT);
let table = get_table::<FORMAT, MASK, SHIFT>();
algorithm(self, radix, table, buffer)
}
}
)*);
}
radix_impl! { u8 u16 u32 u64 usize }
impl Radix for u128 {
#[inline(always)]
fn radix<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
self,
buffer: &mut [u8],
) -> usize {
let table = get_table::<FORMAT, MASK, SHIFT>();
algorithm_u128::<FORMAT, MASK, SHIFT>(self, table, buffer)
}
}