lexical_write_integer/
api.rs1#![doc(hidden)]
4
5use crate::options::Options;
6use crate::write::WriteInteger;
7use lexical_util::assert::{assert_buffer, debug_assert_buffer};
8use lexical_util::format::{NumberFormat, STANDARD};
9use lexical_util::num::SignedInteger;
10use lexical_util::{to_lexical, to_lexical_with_options};
11
12#[inline]
21unsafe fn unsigned<Narrow, Wide, const FORMAT: u128>(value: Narrow, buffer: &mut [u8]) -> usize
22where
23 Narrow: WriteInteger,
24 Wide: WriteInteger,
25{
26 let format = NumberFormat::<FORMAT> {};
27 if cfg!(feature = "format") && format.required_mantissa_sign() {
28 unsafe {
30 index_unchecked_mut!(buffer[0]) = b'+';
31 let buffer = &mut index_unchecked_mut!(buffer[1..]);
32 value.write_mantissa::<Wide, FORMAT>(buffer) + 1
33 }
34 } else {
35 unsafe { value.write_mantissa::<Wide, FORMAT>(buffer) }
37 }
38}
39
40#[inline]
49unsafe fn signed<Narrow, Wide, Unsigned, const FORMAT: u128>(
50 value: Narrow,
51 buffer: &mut [u8],
52) -> usize
53where
54 Narrow: SignedInteger,
55 Wide: SignedInteger,
56 Unsigned: WriteInteger,
57{
58 let format = NumberFormat::<FORMAT> {};
59 if value < Narrow::ZERO {
60 let value = Wide::as_cast(value);
65 let unsigned = Unsigned::as_cast(value.wrapping_neg());
66 unsafe {
68 index_unchecked_mut!(buffer[0]) = b'-';
69 let buffer = &mut index_unchecked_mut!(buffer[1..]);
70 unsigned.write_mantissa::<Unsigned, FORMAT>(buffer) + 1
71 }
72 } else if cfg!(feature = "format") && format.required_mantissa_sign() {
73 let unsigned = Unsigned::as_cast(value);
74 unsafe {
76 index_unchecked_mut!(buffer[0]) = b'+';
77 let buffer = &mut index_unchecked_mut!(buffer[1..]);
78 unsigned.write_mantissa::<Unsigned, FORMAT>(buffer) + 1
79 }
80 } else {
81 let unsigned = Unsigned::as_cast(value);
82 unsafe { unsigned.write_mantissa::<Unsigned, FORMAT>(buffer) }
84 }
85}
86
87macro_rules! unsigned_to_lexical {
91 ($($narrow:tt $wide:tt $(, #[$meta:meta])? ; )*) => ($(
92 impl ToLexical for $narrow {
93 $(#[$meta:meta])?
94 unsafe fn to_lexical_unchecked<'a>(self, bytes: &'a mut [u8])
95 -> &'a mut [u8]
96 {
97 debug_assert_buffer::<$narrow>(10, bytes.len());
98 unsafe {
100 let len = unsigned::<$narrow, $wide, { STANDARD }>(self, bytes);
101 &mut index_unchecked_mut!(bytes[..len])
102 }
103 }
104
105 $(#[$meta:meta])?
106 fn to_lexical<'a>(self, bytes: &'a mut [u8])
107 -> &'a mut [u8]
108 {
109 assert_buffer::<$narrow>(10, bytes.len());
110 unsafe { self.to_lexical_unchecked(bytes) }
112 }
113 }
114
115 impl ToLexicalWithOptions for $narrow {
116 type Options = Options;
117
118 $(#[$meta:meta])?
119 unsafe fn to_lexical_with_options_unchecked<'a, const FORMAT: u128>(
120 self,
121 bytes: &'a mut [u8],
122 _: &Self::Options,
123 ) -> &'a mut [u8]
124 {
125 debug_assert_buffer::<$narrow>(NumberFormat::<{ FORMAT }>::RADIX, bytes.len());
126 assert!(NumberFormat::<{ FORMAT }> {}.is_valid());
127 unsafe {
129 let len = unsigned::<$narrow, $wide, FORMAT>(self, bytes);
130 &mut index_unchecked_mut!(bytes[..len])
131 }
132 }
133
134 $(#[$meta:meta])?
135 fn to_lexical_with_options<'a, const FORMAT: u128>(
136 self,
137 bytes: &'a mut [u8],
138 options: &Self::Options,
139 ) -> &'a mut [u8]
140 {
141 assert_buffer::<$narrow>(NumberFormat::<{ FORMAT }>::RADIX, bytes.len());
142 assert!(NumberFormat::<{ FORMAT }> {}.is_valid());
143 unsafe { self.to_lexical_with_options_unchecked::<FORMAT>(bytes, options) }
145 }
146 }
147 )*)
148}
149
150to_lexical! {}
151to_lexical_with_options! {}
152unsigned_to_lexical! {
153 u8 u32 ;
154 u16 u32 ;
155 u32 u32 ;
156 u64 u64 ;
157 u128 u128 ;
158}
159
160#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
161unsigned_to_lexical! { usize u32 ; }
162
163#[cfg(target_pointer_width = "64")]
164unsigned_to_lexical! { usize u64 ; }
165
166macro_rules! signed_to_lexical {
168 ($($narrow:tt $wide:tt $unsigned:tt $(, #[$meta:meta])? ; )*) => ($(
169 impl ToLexical for $narrow {
170 $(#[$meta:meta])?
171 unsafe fn to_lexical_unchecked<'a>(self, bytes: &'a mut [u8])
172 -> &'a mut [u8]
173 {
174 debug_assert_buffer::<$narrow>(10, bytes.len());
175 unsafe {
177 let len = signed::<$narrow, $wide, $unsigned, { STANDARD }>(self, bytes);
178 &mut index_unchecked_mut!(bytes[..len])
179 }
180 }
181
182 $(#[$meta:meta])?
183 fn to_lexical<'a>(self, bytes: &'a mut [u8])
184 -> &'a mut [u8]
185 {
186 assert_buffer::<$narrow>(10, bytes.len());
187 unsafe { self.to_lexical_unchecked(bytes) }
189 }
190 }
191
192 impl ToLexicalWithOptions for $narrow {
193 type Options = Options;
194
195 $(#[$meta:meta])?
196 unsafe fn to_lexical_with_options_unchecked<'a, const FORMAT: u128>(
197 self,
198 bytes: &'a mut [u8],
199 _: &Self::Options,
200 ) -> &'a mut [u8]
201 {
202 debug_assert_buffer::<$narrow>(NumberFormat::<{ FORMAT }>::RADIX, bytes.len());
203 assert!(NumberFormat::<{ FORMAT }> {}.is_valid());
204 unsafe {
206 let len = signed::<$narrow, $wide, $unsigned, FORMAT>(self, bytes);
207 &mut index_unchecked_mut!(bytes[..len])
208 }
209 }
210
211 $(#[$meta:meta])?
212 fn to_lexical_with_options<'a, const FORMAT: u128>(
213 self,
214 bytes: &'a mut [u8],
215 options: &Self::Options,
216 ) -> &'a mut [u8]
217 {
218 assert_buffer::<$narrow>(NumberFormat::<{ FORMAT }>::RADIX, bytes.len());
219 assert!(NumberFormat::<{ FORMAT }> {}.is_valid());
220 unsafe { self.to_lexical_with_options_unchecked::<FORMAT>(bytes, options) }
222 }
223 }
224 )*)
225}
226
227signed_to_lexical! {
228 i8 i32 u32 ;
229 i16 i32 u32 ;
230 i32 i32 u32 ;
231 i64 i64 u64 ;
232 i128 i128 u128 ;
233}
234
235#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
236signed_to_lexical! { isize i32 u32 ; }
237
238#[cfg(target_pointer_width = "64")]
239signed_to_lexical! { isize i64 u64 ; }