Skip to main content

projective_grid/
float.rs

1//! Sealed [`Float`] trait alias used throughout the crate.
2//!
3//! Every algorithm in this crate is generic over `F: Float`, where `Float`
4//! is `nalgebra::RealField + Copy + From<f32> + 'static`.
5//!
6//! ## Sealed
7//!
8//! The trait is sealed (callers cannot add their own `impl Float for MyType`)
9//! to keep the trait bound semver-flexible. Extending the bound (for example
10//! by adding a `kiddo::float::kdtree::Axis` super-bound) becomes a non-breaking
11//! change: external types that already satisfy the blanket `impl<T: …> Float for T`
12//! pick up the new bound automatically; types that don't were never callable
13//! in the first place.
14//!
15//! ## Why `From<f32>`
16//!
17//! Literal constants — `0.5`, the histogram smoothing weights, `π / 6`, etc.
18//! — are expressed via `F::from(0.5_f32)`. The `From<f32>` bound makes that
19//! conversion total instead of going through `nalgebra`'s `SupersetOf`
20//! machinery. Both `f32` and `f64` implement `From<f32>` directly, so the
21//! two common instantiations Just Work.
22
23mod sealed {
24    /// Sealed marker trait. Implemented for every type that satisfies the
25    /// public `Float` super-bound; callers cannot add their own impls.
26    pub trait Seal {}
27    impl<T> Seal for T where T: nalgebra::RealField + Copy + From<f32> + 'static {}
28}
29
30/// Float type alias used throughout the crate.
31///
32/// Constraints:
33///
34/// * [`nalgebra::RealField`] — the algorithm-shaped numeric bound (covers
35///   arithmetic, ordering, transcendentals, `pi()`, `default_epsilon()`).
36/// * [`Copy`] — every Float value is small enough to pass by value.
37/// * `From<f32>` — literal constants convert directly via `F::from(0.5_f32)`.
38/// * `'static` — required by `kiddo` and serde where the bound surfaces.
39///
40/// The bound is sealed via a private `Seal` super-trait so that
41/// extending the constraint in a future minor release is non-breaking.
42pub trait Float: nalgebra::RealField + Copy + From<f32> + 'static + sealed::Seal {}
43
44impl<T> Float for T where T: nalgebra::RealField + Copy + From<f32> + 'static {}
45
46/// Convert an `f32` literal to `F`. Avoids the `From::from` vs `NumCast::from`
47/// ambiguity that fires when `RealField` brings `num_traits::NumCast` into
48/// scope — `<F as From<f32>>::from(...)` works but reads worse than this
49/// helper. Internal use; not re-exported at the crate root.
50#[inline]
51pub(crate) fn lit<F: Float>(value: f32) -> F {
52    <F as From<f32>>::from(value)
53}