1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-27 07:03:14 -04:00
Files
egui/crates/emath/src/ordered_float.rs
Nicolas 343c3d16c3 Remove wildcard imports (#5018)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

I removed (I hope so) all wildcard imports I found.

For me on my pc this improved the build time:
- for egui -5s
- for eframe -12s

* [x] I have followed the instructions in the PR template
2024-08-28 12:18:42 +02:00

148 lines
3.4 KiB
Rust

//! Total order on floating point types.
//! Can be used for sorting, min/max computation, and other collection algorithms.
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
/// Wraps a floating-point value to add total order and hash.
/// Possible types for `T` are `f32` and `f64`.
///
/// All NaNs are considered equal to each other.
/// The size of zero is ignored.
///
/// See also [`Float`].
#[derive(Clone, Copy)]
pub struct OrderedFloat<T>(pub T);
impl<T: Float + Copy> OrderedFloat<T> {
#[inline]
pub fn into_inner(self) -> T {
self.0
}
}
impl<T: Float> Eq for OrderedFloat<T> {}
impl<T: Float> PartialEq<Self> for OrderedFloat<T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
// NaNs are considered equal (equivalent) when it comes to ordering
if self.0.is_nan() {
other.0.is_nan()
} else {
self.0 == other.0
}
}
}
impl<T: Float> PartialOrd<Self> for OrderedFloat<T> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T: Float> Ord for OrderedFloat<T> {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
match self.0.partial_cmp(&other.0) {
Some(ord) => ord,
None => self.0.is_nan().cmp(&other.0.is_nan()),
}
}
}
impl<T: Float> Hash for OrderedFloat<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl<T> From<T> for OrderedFloat<T> {
#[inline]
fn from(val: T) -> Self {
Self(val)
}
}
// ----------------------------------------------------------------------------
/// Extension trait to provide `ord()` method.
///
/// Example with `f64`:
/// ```
/// use emath::Float as _;
///
/// let array = [1.0, 2.5, 2.0];
/// let max = array.iter().max_by_key(|val| val.ord());
///
/// assert_eq!(max, Some(&2.5));
/// ```
pub trait Float: PartialOrd + PartialEq + private::FloatImpl {
/// Type to provide total order, useful as key in sorted contexts.
fn ord(self) -> OrderedFloat<Self>
where
Self: Sized;
}
impl Float for f32 {
#[inline]
fn ord(self) -> OrderedFloat<Self> {
OrderedFloat(self)
}
}
impl Float for f64 {
#[inline]
fn ord(self) -> OrderedFloat<Self> {
OrderedFloat(self)
}
}
// Keep this trait in private module, to avoid exposing its methods as extensions in user code
mod private {
use super::{Hash, Hasher};
pub trait FloatImpl {
fn is_nan(&self) -> bool;
fn hash<H: Hasher>(&self, state: &mut H);
}
impl FloatImpl for f32 {
#[inline]
fn is_nan(&self) -> bool {
Self::is_nan(*self)
}
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
if *self == 0.0 {
state.write_u8(0);
} else if self.is_nan() {
state.write_u8(1);
} else {
self.to_bits().hash(state);
}
}
}
impl FloatImpl for f64 {
#[inline]
fn is_nan(&self) -> bool {
Self::is_nan(*self)
}
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
if *self == 0.0 {
state.write_u8(0);
} else if self.is_nan() {
state.write_u8(1);
} else {
self.to_bits().hash(state);
}
}
}
}