Skip to content

Commit 2314842

Browse files
authored
Merge pull request #4 from cuviper/super-float-to-int
Make `PrimitiveFloatToInt` a supertrait of `PrimitiveFloat`
2 parents e0607b0 + 34bb21b commit 2314842

5 files changed

Lines changed: 55 additions & 21 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
/Cargo.lock
12
/target

Cargo.lock

Lines changed: 0 additions & 7 deletions
This file was deleted.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "num-primitive"
3-
version = "0.1.1"
3+
version = "0.2.0"
44
description = "Traits for primitive numeric types"
55
repository = "https://github.com/rust-num/num-primitive"
66
license = "MIT OR Apache-2.0"

src/float.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,22 @@ struct SealedToken;
5454
/// assert_eq!(distance_squared::<f64>(&[0., 1., 2.], &[1., 3., 0.]), 9.);
5555
/// ```
5656
pub trait PrimitiveFloat:
57-
PrimitiveNumber + From<i8> + From<u8> + core::ops::Neg<Output = Self>
57+
PrimitiveNumber
58+
+ PrimitiveFloatToInt<i8>
59+
+ PrimitiveFloatToInt<i16>
60+
+ PrimitiveFloatToInt<i32>
61+
+ PrimitiveFloatToInt<i64>
62+
+ PrimitiveFloatToInt<i128>
63+
+ PrimitiveFloatToInt<isize>
64+
+ PrimitiveFloatToInt<u8>
65+
+ PrimitiveFloatToInt<u16>
66+
+ PrimitiveFloatToInt<u32>
67+
+ PrimitiveFloatToInt<u64>
68+
+ PrimitiveFloatToInt<u128>
69+
+ PrimitiveFloatToInt<usize>
70+
+ core::convert::From<i8>
71+
+ core::convert::From<u8>
72+
+ core::ops::Neg<Output = Self>
5873
{
5974
/// Approximate number of significant digits in base 10.
6075
const DIGITS: u32;
@@ -405,7 +420,42 @@ pub trait PrimitiveFloatRef<T>: PrimitiveNumberRef<T> + core::ops::Neg<Output =
405420
///
406421
/// This is effectively the same as the unstable [`core::convert::FloatToInt`], implemented for all
407422
/// combinations of [`PrimitiveFloat`] and [`PrimitiveInteger`][crate::PrimitiveInteger].
408-
pub trait PrimitiveFloatToInt<Int>: PrimitiveFloat {
423+
///
424+
/// # Examples
425+
///
426+
/// `PrimitiveFloatToInt<{integer}>` is a supertrait of [`PrimitiveFloat`] for all primitive
427+
/// integers, so you do not need to use this trait directly with concrete integer types.
428+
///
429+
/// ```
430+
/// use num_primitive::PrimitiveFloat;
431+
///
432+
/// fn pi<Float: PrimitiveFloat>() -> i32 {
433+
/// // SAFETY: π is finite, and truncated to 3 fits any int
434+
/// unsafe { Float::PI.to_int_unchecked() }
435+
/// }
436+
///
437+
/// assert_eq!(pi::<f32>(), 3i32);
438+
/// assert_eq!(pi::<f64>(), 3i32);
439+
/// ```
440+
///
441+
/// However, if the integer type is also generic, an explicit type constraint is needed.
442+
///
443+
/// ```
444+
/// use num_primitive::{PrimitiveFloat, PrimitiveFloatToInt};
445+
///
446+
/// fn tau<Float, Int>() -> Int
447+
/// where
448+
/// Float: PrimitiveFloat + PrimitiveFloatToInt<Int>,
449+
/// {
450+
/// // SAFETY: τ is finite, and truncated to 6 fits any int
451+
/// unsafe { Float::TAU.to_int_unchecked() }
452+
/// }
453+
///
454+
/// assert_eq!(tau::<f32, i64>(), 6i64);
455+
/// assert_eq!(tau::<f64, u8>(), 6u8);
456+
/// ```
457+
///
458+
pub trait PrimitiveFloatToInt<Int> {
409459
#[doc(hidden)]
410460
#[expect(private_interfaces)]
411461
unsafe fn __to_int_unchecked(x: Self, _: SealedToken) -> Int;

src/tests.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extern crate alloc;
1717
use alloc::boxed::Box;
1818
use core::error::Error;
1919

20-
use crate::{PrimitiveError, PrimitiveFloatToInt, PrimitiveInteger, PrimitiveNumber};
20+
use crate::{PrimitiveError, PrimitiveInteger, PrimitiveNumber};
2121

2222
fn check_result<'a, T: PrimitiveNumber, E: PrimitiveError>(r: Result<T, E>, ok: T) {
2323
// Cloning and equating results requires `E: Clone + PartialEq`
@@ -58,13 +58,3 @@ fn try_into() {
5858
}
5959
check(0i32, 0u32);
6060
}
61-
62-
#[test]
63-
fn to_int_unchecked() {
64-
fn pi<T: PrimitiveFloatToInt<Int>, Int>() -> Int {
65-
// SAFETY: π is finite, and truncated to 3 fits any int
66-
unsafe { T::PI.to_int_unchecked() }
67-
}
68-
assert_eq!(pi::<f32, i64>(), 3i64);
69-
assert_eq!(pi::<f64, u8>(), 3u8);
70-
}

0 commit comments

Comments
 (0)