lexical_write_integer/write.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
//! Shared trait and methods for writing integers.
#![doc(hidden)]
use lexical_util::format;
/// Select the back-end.
#[cfg(feature = "compact")]
use crate::compact::Compact;
#[cfg(not(feature = "compact"))]
use crate::decimal::Decimal;
#[cfg(all(not(feature = "compact"), feature = "power-of-two"))]
use crate::radix::Radix;
/// Define the implementation to write significant digits.
macro_rules! write_mantissa {
($($t:tt)+) => {
/// Internal implementation to write significant digits for float writers.
#[doc(hidden)]
#[inline(always)]
fn write_mantissa<const FORMAT: u128>(self, buffer: &mut [u8]) -> usize {
self.write_integer::<FORMAT, { format::RADIX }, { format::RADIX_SHIFT }>(buffer)
}
/// Internal implementation to write significant digits for float writers.
#[doc(hidden)]
#[inline(always)]
fn write_mantissa_signed<const FORMAT: u128>(self, buffer: &mut [u8]) -> usize {
self.write_integer_signed::<FORMAT, { format::RADIX }, { format::RADIX_SHIFT }>(buffer)
}
};
}
/// Define the implementation to write exponent digits.
macro_rules! write_exponent {
($($t:tt)+) => (
// NOTE: This should always be signed, but for backwards compatibility as
// a precaution we keep the original just in case someone uses the private API.
/// Internal implementation to write exponent digits for float writers.
// NOTE: This is not part of the public API.
#[doc(hidden)]
#[inline(always)]
#[deprecated = "use `write_exponent_signed`, since exponents are always signed."]
fn write_exponent<const FORMAT: u128>(self, buffer: &mut [u8]) -> usize
{
self.write_integer::<FORMAT, { format::EXPONENT_RADIX }, { format::EXPONENT_RADIX_SHIFT }>(buffer)
}
/// Internal implementation to write exponent digits for float writers.
#[doc(hidden)]
#[inline(always)]
fn write_exponent_signed<const FORMAT: u128>(self, buffer: &mut [u8]) -> usize
{
self.write_integer_signed::<FORMAT, { format::EXPONENT_RADIX }, { format::EXPONENT_RADIX_SHIFT }>(buffer)
}
)
}
/// Write integer trait, implemented in terms of the compact back-end.
#[cfg(feature = "compact")]
pub trait WriteInteger: Compact {
/// Forward write integer parameters to an unoptimized backend.
///
/// # Preconditions
///
/// `self` must be non-negative and unsigned.
///
/// [`FORMATTED_SIZE`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE
/// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
fn write_integer<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
self,
buffer: &mut [u8],
) -> usize {
let radix = format::radix_from_flags(FORMAT, MASK, SHIFT);
self.compact(radix, buffer)
}
/// Forward write integer parameters to an optimized backend.
///
/// This requires a type that was previously signed.
///
/// # Preconditions
///
/// `self` must be non-negative but is `>= 0` and `<= Signed::MAX`.
///
/// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
#[inline(always)]
fn write_integer_signed<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
self,
buffer: &mut [u8],
) -> usize {
self.write_integer::<FORMAT, MASK, SHIFT>(buffer)
}
write_mantissa!(Compact);
write_exponent!(Compact);
}
/// Write integer trait, implemented in terms of the optimized, decimal
/// back-end.
#[cfg(all(not(feature = "compact"), not(feature = "power-of-two")))]
pub trait WriteInteger: Decimal {
/// Forward write integer parameters to an optimized backend.
///
/// # Preconditions
///
/// `self` must be non-negative and unsigned.
///
/// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
#[inline(always)]
fn write_integer<const __: u128, const ___: u128, const ____: i32>(
self,
buffer: &mut [u8],
) -> usize {
self.decimal(buffer)
}
/// Forward write integer parameters to an optimized backend.
///
/// This requires a type that was previously signed.
///
/// # Preconditions
///
/// `self` must be non-negative but is `>= 0` and `<= Signed::MAX`.
///
/// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
#[inline(always)]
fn write_integer_signed<const __: u128, const ___: u128, const ____: i32>(
self,
buffer: &mut [u8],
) -> usize {
self.decimal_signed(buffer)
}
write_mantissa!(Decimal);
write_exponent!(Decimal);
}
/// Write integer trait, implemented in terms of the optimized, decimal or radix
/// back-end.
#[cfg(all(not(feature = "compact"), feature = "power-of-two"))]
pub trait WriteInteger: Decimal + Radix {
/// Forward write integer parameters to an optimized backend.
///
/// # Preconditions
///
/// `self` must be non-negative and unsigned.
///
/// [`FORMATTED_SIZE`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE
/// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
#[inline(always)]
fn write_integer<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
self,
buffer: &mut [u8],
) -> usize {
if format::radix_from_flags(FORMAT, MASK, SHIFT) == 10 {
self.decimal(buffer)
} else {
self.radix::<FORMAT, MASK, SHIFT>(buffer)
}
}
/// Forward write integer parameters to an optimized backend.
///
/// This requires a type that was previously signed.
///
/// # Preconditions
///
/// `self` must be non-negative but is `>= 0` and `<= Signed::MAX`.
///
/// [`FORMATTED_SIZE_DECIMAL`]: lexical_util::constants::FormattedSize::FORMATTED_SIZE_DECIMAL
#[inline(always)]
fn write_integer_signed<const FORMAT: u128, const MASK: u128, const SHIFT: i32>(
self,
buffer: &mut [u8],
) -> usize {
if format::radix_from_flags(FORMAT, MASK, SHIFT) == 10 {
self.decimal_signed(buffer)
} else {
self.radix::<FORMAT, MASK, SHIFT>(buffer)
}
}
write_mantissa!(Decimal + Radix);
write_exponent!(Decimal + Radix);
}
macro_rules! write_integer_impl {
($($t:ty)*) => ($(
impl WriteInteger for $t {}
)*)
}
write_integer_impl! { u8 u16 u32 u64 u128 usize }