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