Add `emath::OrderedFloat` (moved from `epaint::util::OrderedFloat`) (#4389)
It makes much more sense in `emath`
This commit is contained in:
parent
46b241eb94
commit
87b294534e
|
|
@ -1242,6 +1242,7 @@ dependencies = [
|
|||
"ahash",
|
||||
"backtrace",
|
||||
"document-features",
|
||||
"emath",
|
||||
"epaint",
|
||||
"log",
|
||||
"nohash-hasher",
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ impl std::ops::IndexMut<usize> for Rgba {
|
|||
}
|
||||
}
|
||||
|
||||
/// Deterministically hash an `f32`, treating all NANs as equal, and ignoring the sign of zero.
|
||||
#[inline]
|
||||
pub(crate) fn f32_hash<H: std::hash::Hasher>(state: &mut H, f: f32) {
|
||||
if f == 0.0 {
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ unity = ["epaint/unity"]
|
|||
|
||||
|
||||
[dependencies]
|
||||
emath = { workspace = true, default-features = false }
|
||||
epaint = { workspace = true, default-features = false }
|
||||
|
||||
ahash.workspace = true
|
||||
|
|
|
|||
|
|
@ -55,23 +55,21 @@
|
|||
mod bytes_loader;
|
||||
mod texture_loader;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Debug;
|
||||
use std::ops::Deref;
|
||||
use std::{fmt::Display, sync::Arc};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
fmt::{Debug, Display},
|
||||
ops::Deref,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use ahash::HashMap;
|
||||
|
||||
use epaint::mutex::Mutex;
|
||||
use epaint::util::FloatOrd;
|
||||
use epaint::util::OrderedFloat;
|
||||
use epaint::TextureHandle;
|
||||
use epaint::{textures::TextureOptions, ColorImage, TextureId, Vec2};
|
||||
use emath::{Float, OrderedFloat};
|
||||
use epaint::{mutex::Mutex, textures::TextureOptions, ColorImage, TextureHandle, TextureId, Vec2};
|
||||
|
||||
use crate::Context;
|
||||
|
||||
pub use self::bytes_loader::DefaultBytesLoader;
|
||||
pub use self::texture_loader::DefaultTextureLoader;
|
||||
pub use self::{bytes_loader::DefaultBytesLoader, texture_loader::DefaultTextureLoader};
|
||||
|
||||
/// Represents a failed attempt at loading an image.
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use crate::load::TextureLoadResult;
|
||||
use emath::{Float as _, Rot2};
|
||||
use epaint::RectShape;
|
||||
|
||||
use crate::{
|
||||
load::{Bytes, SizeHint, SizedTexture, TexturePoll},
|
||||
load::{Bytes, SizeHint, SizedTexture, TextureLoadResult, TexturePoll},
|
||||
*,
|
||||
};
|
||||
use emath::Rot2;
|
||||
use epaint::{util::FloatOrd, RectShape};
|
||||
|
||||
/// A widget which displays an image.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use epaint::{emath::Rot2, util::FloatOrd, Mesh};
|
||||
use epaint::{emath::Rot2, Mesh};
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ use std::{cmp::Ordering, ops::RangeInclusive, sync::Arc};
|
|||
|
||||
use egui::ahash::HashMap;
|
||||
use egui::*;
|
||||
use epaint::{util::FloatOrd, Hsva};
|
||||
use emath::Float as _;
|
||||
use epaint::Hsva;
|
||||
|
||||
pub use crate::{
|
||||
axis::{Axis, AxisHints, HPlacement, Placement, VPlacement},
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ use std::ops::{Add, Div, Mul, RangeInclusive, Sub};
|
|||
pub mod align;
|
||||
mod history;
|
||||
mod numeric;
|
||||
mod ordered_float;
|
||||
mod pos2;
|
||||
mod range;
|
||||
mod rect;
|
||||
|
|
@ -40,10 +41,11 @@ mod ts_transform;
|
|||
mod vec2;
|
||||
mod vec2b;
|
||||
|
||||
pub use {
|
||||
pub use self::{
|
||||
align::{Align, Align2},
|
||||
history::History,
|
||||
numeric::*,
|
||||
ordered_float::*,
|
||||
pos2::*,
|
||||
range::Rangef,
|
||||
rect::*,
|
||||
|
|
|
|||
|
|
@ -7,9 +7,12 @@ use std::hash::{Hash, Hasher};
|
|||
/// Wraps a floating-point value to add total order and hash.
|
||||
/// Possible types for `T` are `f32` and `f64`.
|
||||
///
|
||||
/// See also [`FloatOrd`].
|
||||
/// All NaNs are considered equal to each other.
|
||||
/// The size of zero is ignored.
|
||||
///
|
||||
/// See also [`Float`].
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct OrderedFloat<T>(T);
|
||||
pub struct OrderedFloat<T>(pub T);
|
||||
|
||||
impl<T: Float + Copy> OrderedFloat<T> {
|
||||
#[inline]
|
||||
|
|
@ -68,44 +71,34 @@ impl<T> From<T> for OrderedFloat<T> {
|
|||
///
|
||||
/// Example with `f64`:
|
||||
/// ```
|
||||
/// use epaint::util::FloatOrd;
|
||||
/// 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 FloatOrd {
|
||||
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 FloatOrd for f32 {
|
||||
impl Float for f32 {
|
||||
#[inline]
|
||||
fn ord(self) -> OrderedFloat<Self> {
|
||||
OrderedFloat(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl FloatOrd for f64 {
|
||||
impl Float for f64 {
|
||||
#[inline]
|
||||
fn ord(self) -> OrderedFloat<Self> {
|
||||
OrderedFloat(self)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Internal abstraction over floating point types
|
||||
#[doc(hidden)]
|
||||
pub trait Float: PartialOrd + PartialEq + private::FloatImpl {}
|
||||
|
||||
impl Float for f32 {}
|
||||
|
||||
impl Float for f64 {}
|
||||
|
||||
// Keep this trait in private module, to avoid exposing its methods as extensions in user code
|
||||
mod private {
|
||||
use super::*;
|
||||
|
|
@ -124,7 +117,13 @@ mod private {
|
|||
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
crate::f32_hash(state, *self);
|
||||
if *self == 0.0 {
|
||||
state.write_u8(0);
|
||||
} else if self.is_nan() {
|
||||
state.write_u8(1);
|
||||
} else {
|
||||
self.to_bits().hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,7 +135,13 @@ mod private {
|
|||
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
crate::f64_hash(state, *self);
|
||||
if *self == 0.0 {
|
||||
state.write_u8(0);
|
||||
} else if self.is_nan() {
|
||||
state.write_u8(1);
|
||||
} else {
|
||||
self.to_bits().hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -152,32 +152,6 @@ macro_rules! epaint_assert {
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn f32_hash<H: std::hash::Hasher>(state: &mut H, f: f32) {
|
||||
if f == 0.0 {
|
||||
state.write_u8(0);
|
||||
} else if f.is_nan() {
|
||||
state.write_u8(1);
|
||||
} else {
|
||||
use std::hash::Hash;
|
||||
f.to_bits().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn f64_hash<H: std::hash::Hasher>(state: &mut H, f: f64) {
|
||||
if f == 0.0 {
|
||||
state.write_u8(0);
|
||||
} else if f.is_nan() {
|
||||
state.write_u8(1);
|
||||
} else {
|
||||
use std::hash::Hash;
|
||||
f.to_bits().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Was epaint compiled with the `rayon` feature?
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ impl std::hash::Hash for Stroke {
|
|||
#[inline(always)]
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
let Self { width, color } = *self;
|
||||
crate::f32_hash(state, width);
|
||||
emath::OrderedFloat(width).hash(state);
|
||||
color.hash(state);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use crate::{
|
|||
},
|
||||
TextureAtlas,
|
||||
};
|
||||
use emath::NumExt as _;
|
||||
use emath::{NumExt as _, OrderedFloat};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ impl std::hash::Hash for FontId {
|
|||
#[inline(always)]
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
let Self { size, family } = self;
|
||||
crate::f32_hash(state, *size);
|
||||
emath::OrderedFloat(*size).hash(state);
|
||||
family.hash(state);
|
||||
}
|
||||
}
|
||||
|
|
@ -567,21 +567,6 @@ impl FontsAndCache {
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
struct HashableF32(f32);
|
||||
|
||||
#[allow(clippy::derived_hash_with_manual_eq)]
|
||||
impl std::hash::Hash for HashableF32 {
|
||||
#[inline(always)]
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
crate::f32_hash(state, self.0);
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for HashableF32 {}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// The collection of fonts used by `epaint`.
|
||||
///
|
||||
/// Required in order to paint text.
|
||||
|
|
@ -591,7 +576,7 @@ pub struct FontsImpl {
|
|||
definitions: FontDefinitions,
|
||||
atlas: Arc<Mutex<TextureAtlas>>,
|
||||
font_impl_cache: FontImplCache,
|
||||
sized_family: ahash::HashMap<(HashableF32, FontFamily), Font>,
|
||||
sized_family: ahash::HashMap<(OrderedFloat<f32>, FontFamily), Font>,
|
||||
}
|
||||
|
||||
impl FontsImpl {
|
||||
|
|
@ -641,7 +626,7 @@ impl FontsImpl {
|
|||
let FontId { size, family } = font_id;
|
||||
|
||||
self.sized_family
|
||||
.entry((HashableF32(*size), family.clone()))
|
||||
.entry((OrderedFloat(*size), family.clone()))
|
||||
.or_insert_with(|| {
|
||||
let fonts = &self.definitions.families.get(family);
|
||||
let fonts = fonts
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ impl std::hash::Hash for LayoutJob {
|
|||
text.hash(state);
|
||||
sections.hash(state);
|
||||
wrap.hash(state);
|
||||
crate::f32_hash(state, *first_row_min_height);
|
||||
emath::OrderedFloat(*first_row_min_height).hash(state);
|
||||
break_on_newline.hash(state);
|
||||
halign.hash(state);
|
||||
justify.hash(state);
|
||||
|
|
@ -214,7 +214,7 @@ impl std::hash::Hash for LayoutSection {
|
|||
byte_range,
|
||||
format,
|
||||
} = self;
|
||||
crate::f32_hash(state, *leading_space);
|
||||
OrderedFloat(*leading_space).hash(state);
|
||||
byte_range.hash(state);
|
||||
format.hash(state);
|
||||
}
|
||||
|
|
@ -293,9 +293,9 @@ impl std::hash::Hash for TextFormat {
|
|||
valign,
|
||||
} = self;
|
||||
font_id.hash(state);
|
||||
crate::f32_hash(state, *extra_letter_spacing);
|
||||
emath::OrderedFloat(*extra_letter_spacing).hash(state);
|
||||
if let Some(line_height) = *line_height {
|
||||
crate::f32_hash(state, line_height);
|
||||
emath::OrderedFloat(line_height).hash(state);
|
||||
}
|
||||
color.hash(state);
|
||||
background.hash(state);
|
||||
|
|
@ -375,7 +375,7 @@ impl std::hash::Hash for TextWrapping {
|
|||
break_anywhere,
|
||||
overflow_character,
|
||||
} = self;
|
||||
crate::f32_hash(state, *max_width);
|
||||
emath::OrderedFloat(*max_width).hash(state);
|
||||
max_rows.hash(state);
|
||||
break_anywhere.hash(state);
|
||||
overflow_character.hash(state);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
mod ordered_float;
|
||||
|
||||
pub use ordered_float::*;
|
||||
#[deprecated = "Use emath::OrderedFloat instead"]
|
||||
pub use emath::OrderedFloat;
|
||||
|
||||
/// Hash the given value with a predictable hasher.
|
||||
#[inline]
|
||||
|
|
|
|||
Loading…
Reference in New Issue