Skip to content

Commit d195eaf

Browse files
committed
Simplify the to_primitive_float macros
1 parent f6dc4d2 commit d195eaf

File tree

1 file changed

+64
-85
lines changed

1 file changed

+64
-85
lines changed

src/cast.rs

Lines changed: 64 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -223,112 +223,91 @@ impl_to_primitive_uint!(u32);
223223
impl_to_primitive_uint!(u64);
224224

225225
macro_rules! impl_to_primitive_float_to_float {
226-
($SrcT:ident, $DstT:ident, $slf:expr) => ({
227-
// Only finite values that are reducing size need to worry about overflow.
228-
if size_of::<$SrcT>() > size_of::<$DstT>() && FloatCore::is_finite($slf) {
229-
let n = $slf as f64;
230-
if n < $DstT::MIN as f64 || n > $DstT::MAX as f64 {
231-
return None;
226+
($SrcT:ident : $( fn $method:ident -> $DstT:ident ; )*) => {$(
227+
#[inline]
228+
fn $method(&self) -> Option<$DstT> {
229+
// Only finite values that are reducing size need to worry about overflow.
230+
if size_of::<$SrcT>() > size_of::<$DstT>() && FloatCore::is_finite(*self) {
231+
let n = *self as f64;
232+
if n < $DstT::MIN as f64 || n > $DstT::MAX as f64 {
233+
return None;
234+
}
232235
}
236+
// We can safely cast NaN, +-inf, and finite values in range.
237+
Some(*self as $DstT)
233238
}
234-
// We can safely cast NaN, +-inf, and finite values in range.
235-
Some($slf as $DstT)
236-
})
239+
)*}
237240
}
238241

239242
macro_rules! impl_to_primitive_float_to_signed_int {
240-
($SrcT:ident, $DstT:ident, $slf:expr) => ({
241-
let t = $slf.trunc(); // round toward zero.
242-
// MIN is a power of two, which we can cast and compare directly.
243-
if t >= $DstT::MIN as $SrcT {
244-
// The mantissa might not be able to represent all digits of MAX.
245-
let sig_bits = size_of::<$DstT>() as u32 * 8 - 1;
246-
let max = if sig_bits > $SrcT::MANTISSA_DIGITS {
247-
let lost_bits = sig_bits - $SrcT::MANTISSA_DIGITS;
248-
$DstT::MAX & !((1 << lost_bits) - 1)
249-
} else {
250-
$DstT::MAX
251-
};
252-
if t <= max as $SrcT {
253-
return Some($slf as $DstT);
243+
($f:ident : $( fn $method:ident -> $i:ident ; )*) => {$(
244+
#[inline]
245+
fn $method(&self) -> Option<$i> {
246+
let t = self.trunc(); // round toward zero.
247+
// MIN is a power of two, which we can cast and compare directly.
248+
if t >= $i::MIN as $f {
249+
// The mantissa might not be able to represent all digits of MAX.
250+
let sig_bits = size_of::<$i>() as u32 * 8 - 1;
251+
let max = if sig_bits > $f::MANTISSA_DIGITS {
252+
let lost_bits = sig_bits - $f::MANTISSA_DIGITS;
253+
$i::MAX & !((1 << lost_bits) - 1)
254+
} else {
255+
$i::MAX
256+
};
257+
if t <= max as $f {
258+
return Some(*self as $i);
259+
}
254260
}
261+
None
255262
}
256-
None
257-
})
263+
)*}
258264
}
259265

260266
macro_rules! impl_to_primitive_float_to_unsigned_int {
261-
($SrcT:ident, $DstT:ident, $slf:expr) => ({
262-
let t = $slf.trunc(); // round toward zero.
263-
if t >= 0.0 {
264-
// The mantissa might not be able to represent all digits of MAX.
265-
let sig_bits = size_of::<$DstT>() as u32 * 8;
266-
let max = if sig_bits > $SrcT::MANTISSA_DIGITS {
267-
let lost_bits = sig_bits - $SrcT::MANTISSA_DIGITS;
268-
$DstT::MAX & !((1 << lost_bits) - 1)
269-
} else {
270-
$DstT::MAX
271-
};
272-
if t <= max as $SrcT {
273-
return Some($slf as $DstT);
267+
($f:ident : $( fn $method:ident -> $u:ident ; )*) => {$(
268+
#[inline]
269+
fn $method(&self) -> Option<$u> {
270+
let t = self.trunc(); // round toward zero.
271+
if t >= 0.0 {
272+
// The mantissa might not be able to represent all digits of MAX.
273+
let sig_bits = size_of::<$u>() as u32 * 8;
274+
let max = if sig_bits > $f::MANTISSA_DIGITS {
275+
let lost_bits = sig_bits - $f::MANTISSA_DIGITS;
276+
$u::MAX & !((1 << lost_bits) - 1)
277+
} else {
278+
$u::MAX
279+
};
280+
if t <= max as $f {
281+
return Some(*self as $u);
282+
}
274283
}
284+
None
275285
}
276-
None
277-
})
286+
)*}
278287
}
279288

280289
macro_rules! impl_to_primitive_float {
281290
($T:ident) => (
282291
impl ToPrimitive for $T {
283-
#[inline]
284-
fn to_isize(&self) -> Option<isize> {
285-
impl_to_primitive_float_to_signed_int!($T, isize, *self)
286-
}
287-
#[inline]
288-
fn to_i8(&self) -> Option<i8> {
289-
impl_to_primitive_float_to_signed_int!($T, i8, *self)
290-
}
291-
#[inline]
292-
fn to_i16(&self) -> Option<i16> {
293-
impl_to_primitive_float_to_signed_int!($T, i16, *self)
294-
}
295-
#[inline]
296-
fn to_i32(&self) -> Option<i32> {
297-
impl_to_primitive_float_to_signed_int!($T, i32, *self)
298-
}
299-
#[inline]
300-
fn to_i64(&self) -> Option<i64> {
301-
impl_to_primitive_float_to_signed_int!($T, i64, *self)
292+
impl_to_primitive_float_to_signed_int! { $T:
293+
fn to_isize -> isize;
294+
fn to_i8 -> i8;
295+
fn to_i16 -> i16;
296+
fn to_i32 -> i32;
297+
fn to_i64 -> i64;
302298
}
303299

304-
#[inline]
305-
fn to_usize(&self) -> Option<usize> {
306-
impl_to_primitive_float_to_unsigned_int!($T, usize, *self)
307-
}
308-
#[inline]
309-
fn to_u8(&self) -> Option<u8> {
310-
impl_to_primitive_float_to_unsigned_int!($T, u8, *self)
311-
}
312-
#[inline]
313-
fn to_u16(&self) -> Option<u16> {
314-
impl_to_primitive_float_to_unsigned_int!($T, u16, *self)
315-
}
316-
#[inline]
317-
fn to_u32(&self) -> Option<u32> {
318-
impl_to_primitive_float_to_unsigned_int!($T, u32, *self)
319-
}
320-
#[inline]
321-
fn to_u64(&self) -> Option<u64> {
322-
impl_to_primitive_float_to_unsigned_int!($T, u64, *self)
300+
impl_to_primitive_float_to_unsigned_int! { $T:
301+
fn to_usize -> usize;
302+
fn to_u8 -> u8;
303+
fn to_u16 -> u16;
304+
fn to_u32 -> u32;
305+
fn to_u64 -> u64;
323306
}
324307

325-
#[inline]
326-
fn to_f32(&self) -> Option<f32> {
327-
impl_to_primitive_float_to_float!($T, f32, *self)
328-
}
329-
#[inline]
330-
fn to_f64(&self) -> Option<f64> {
331-
impl_to_primitive_float_to_float!($T, f64, *self)
308+
impl_to_primitive_float_to_float! { $T:
309+
fn to_f32 -> f32;
310+
fn to_f64 -> f64;
332311
}
333312
}
334313
)

0 commit comments

Comments
 (0)