Skip to content

Commit 3c7c609

Browse files
emilkhacknus
authored andcommitted
Add emath::OrderedFloat (moved from epaint::util::OrderedFloat) (emilk#4389)
It makes much more sense in `emath`
1 parent ecda55e commit 3c7c609

File tree

14 files changed

+57
-90
lines changed

14 files changed

+57
-90
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ecolor/src/rgba.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ impl std::ops::IndexMut<usize> for Rgba {
2626
}
2727
}
2828

29+
/// Deterministically hash an `f32`, treating all NANs as equal, and ignoring the sign of zero.
2930
#[inline]
3031
pub(crate) fn f32_hash<H: std::hash::Hasher>(state: &mut H, f: f32) {
3132
if f == 0.0 {

crates/egui/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ unity = ["epaint/unity"]
8181

8282

8383
[dependencies]
84+
emath = { workspace = true, default-features = false }
8485
epaint = { workspace = true, default-features = false }
8586

8687
ahash.workspace = true

crates/egui/src/load.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,21 @@
5555
mod bytes_loader;
5656
mod texture_loader;
5757

58-
use std::borrow::Cow;
59-
use std::fmt::Debug;
60-
use std::ops::Deref;
61-
use std::{fmt::Display, sync::Arc};
58+
use std::{
59+
borrow::Cow,
60+
fmt::{Debug, Display},
61+
ops::Deref,
62+
sync::Arc,
63+
};
6264

6365
use ahash::HashMap;
6466

65-
use epaint::mutex::Mutex;
66-
use epaint::util::FloatOrd;
67-
use epaint::util::OrderedFloat;
68-
use epaint::TextureHandle;
69-
use epaint::{textures::TextureOptions, ColorImage, TextureId, Vec2};
67+
use emath::{Float, OrderedFloat};
68+
use epaint::{mutex::Mutex, textures::TextureOptions, ColorImage, TextureHandle, TextureId, Vec2};
7069

7170
use crate::Context;
7271

73-
pub use self::bytes_loader::DefaultBytesLoader;
74-
pub use self::texture_loader::DefaultTextureLoader;
72+
pub use self::{bytes_loader::DefaultBytesLoader, texture_loader::DefaultTextureLoader};
7573

7674
/// Represents a failed attempt at loading an image.
7775
#[derive(Clone, Debug)]

crates/egui/src/widgets/image.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use std::borrow::Cow;
22

3-
use crate::load::TextureLoadResult;
3+
use emath::{Float as _, Rot2};
4+
use epaint::RectShape;
5+
46
use crate::{
5-
load::{Bytes, SizeHint, SizedTexture, TexturePoll},
7+
load::{Bytes, SizeHint, SizedTexture, TextureLoadResult, TexturePoll},
68
*,
79
};
8-
use emath::Rot2;
9-
use epaint::{util::FloatOrd, RectShape};
1010

1111
/// A widget which displays an image.
1212
///

crates/egui_plot/src/items/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use std::ops::RangeInclusive;
55

6-
use epaint::{emath::Rot2, util::FloatOrd, Mesh};
6+
use epaint::{emath::Rot2, Mesh};
77

88
use crate::*;
99

crates/egui_plot/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ use std::{cmp::Ordering, ops::RangeInclusive, sync::Arc};
1717

1818
use egui::ahash::HashMap;
1919
use egui::*;
20-
use epaint::{util::FloatOrd, Hsva};
20+
use emath::Float as _;
21+
use epaint::Hsva;
2122

2223
pub use crate::{
2324
axis::{Axis, AxisHints, HPlacement, Placement, VPlacement},

crates/emath/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use std::ops::{Add, Div, Mul, RangeInclusive, Sub};
3030
pub mod align;
3131
mod history;
3232
mod numeric;
33+
mod ordered_float;
3334
mod pos2;
3435
mod range;
3536
mod rect;
@@ -40,10 +41,11 @@ mod ts_transform;
4041
mod vec2;
4142
mod vec2b;
4243

43-
pub use {
44+
pub use self::{
4445
align::{Align, Align2},
4546
history::History,
4647
numeric::*,
48+
ordered_float::*,
4749
pos2::*,
4850
range::Rangef,
4951
rect::*,

crates/epaint/src/util/ordered_float.rs renamed to crates/emath/src/ordered_float.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ use std::hash::{Hash, Hasher};
77
/// Wraps a floating-point value to add total order and hash.
88
/// Possible types for `T` are `f32` and `f64`.
99
///
10-
/// See also [`FloatOrd`].
10+
/// All NaNs are considered equal to each other.
11+
/// The size of zero is ignored.
12+
///
13+
/// See also [`Float`].
1114
#[derive(Clone, Copy)]
12-
pub struct OrderedFloat<T>(T);
15+
pub struct OrderedFloat<T>(pub T);
1316

1417
impl<T: Float + Copy> OrderedFloat<T> {
1518
#[inline]
@@ -68,44 +71,34 @@ impl<T> From<T> for OrderedFloat<T> {
6871
///
6972
/// Example with `f64`:
7073
/// ```
71-
/// use epaint::util::FloatOrd;
74+
/// use emath::Float as _;
7275
///
7376
/// let array = [1.0, 2.5, 2.0];
7477
/// let max = array.iter().max_by_key(|val| val.ord());
7578
///
7679
/// assert_eq!(max, Some(&2.5));
7780
/// ```
78-
pub trait FloatOrd {
81+
pub trait Float: PartialOrd + PartialEq + private::FloatImpl {
7982
/// Type to provide total order, useful as key in sorted contexts.
8083
fn ord(self) -> OrderedFloat<Self>
8184
where
8285
Self: Sized;
8386
}
8487

85-
impl FloatOrd for f32 {
88+
impl Float for f32 {
8689
#[inline]
8790
fn ord(self) -> OrderedFloat<Self> {
8891
OrderedFloat(self)
8992
}
9093
}
9194

92-
impl FloatOrd for f64 {
95+
impl Float for f64 {
9396
#[inline]
9497
fn ord(self) -> OrderedFloat<Self> {
9598
OrderedFloat(self)
9699
}
97100
}
98101

99-
// ----------------------------------------------------------------------------
100-
101-
/// Internal abstraction over floating point types
102-
#[doc(hidden)]
103-
pub trait Float: PartialOrd + PartialEq + private::FloatImpl {}
104-
105-
impl Float for f32 {}
106-
107-
impl Float for f64 {}
108-
109102
// Keep this trait in private module, to avoid exposing its methods as extensions in user code
110103
mod private {
111104
use super::*;
@@ -124,7 +117,13 @@ mod private {
124117

125118
#[inline]
126119
fn hash<H: Hasher>(&self, state: &mut H) {
127-
crate::f32_hash(state, *self);
120+
if *self == 0.0 {
121+
state.write_u8(0);
122+
} else if self.is_nan() {
123+
state.write_u8(1);
124+
} else {
125+
self.to_bits().hash(state);
126+
}
128127
}
129128
}
130129

@@ -136,7 +135,13 @@ mod private {
136135

137136
#[inline]
138137
fn hash<H: Hasher>(&self, state: &mut H) {
139-
crate::f64_hash(state, *self);
138+
if *self == 0.0 {
139+
state.write_u8(0);
140+
} else if self.is_nan() {
141+
state.write_u8(1);
142+
} else {
143+
self.to_bits().hash(state);
144+
}
140145
}
141146
}
142147
}

crates/epaint/src/lib.rs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -152,32 +152,6 @@ macro_rules! epaint_assert {
152152
}
153153
}
154154

155-
// ----------------------------------------------------------------------------
156-
157-
#[inline(always)]
158-
pub(crate) fn f32_hash<H: std::hash::Hasher>(state: &mut H, f: f32) {
159-
if f == 0.0 {
160-
state.write_u8(0);
161-
} else if f.is_nan() {
162-
state.write_u8(1);
163-
} else {
164-
use std::hash::Hash;
165-
f.to_bits().hash(state);
166-
}
167-
}
168-
169-
#[inline(always)]
170-
pub(crate) fn f64_hash<H: std::hash::Hasher>(state: &mut H, f: f64) {
171-
if f == 0.0 {
172-
state.write_u8(0);
173-
} else if f.is_nan() {
174-
state.write_u8(1);
175-
} else {
176-
use std::hash::Hash;
177-
f.to_bits().hash(state);
178-
}
179-
}
180-
181155
// ---------------------------------------------------------------------------
182156

183157
/// Was epaint compiled with the `rayon` feature?

crates/epaint/src/stroke.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl std::hash::Hash for Stroke {
4848
#[inline(always)]
4949
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
5050
let Self { width, color } = *self;
51-
crate::f32_hash(state, width);
51+
emath::OrderedFloat(width).hash(state);
5252
color.hash(state);
5353
}
5454
}

crates/epaint/src/text/fonts.rs

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
},
99
TextureAtlas,
1010
};
11-
use emath::NumExt as _;
11+
use emath::{NumExt as _, OrderedFloat};
1212

1313
// ----------------------------------------------------------------------------
1414

@@ -56,7 +56,7 @@ impl std::hash::Hash for FontId {
5656
#[inline(always)]
5757
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
5858
let Self { size, family } = self;
59-
crate::f32_hash(state, *size);
59+
emath::OrderedFloat(*size).hash(state);
6060
family.hash(state);
6161
}
6262
}
@@ -567,21 +567,6 @@ impl FontsAndCache {
567567

568568
// ----------------------------------------------------------------------------
569569

570-
#[derive(Clone, Copy, Debug, PartialEq)]
571-
struct HashableF32(f32);
572-
573-
#[allow(clippy::derived_hash_with_manual_eq)]
574-
impl std::hash::Hash for HashableF32 {
575-
#[inline(always)]
576-
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
577-
crate::f32_hash(state, self.0);
578-
}
579-
}
580-
581-
impl Eq for HashableF32 {}
582-
583-
// ----------------------------------------------------------------------------
584-
585570
/// The collection of fonts used by `epaint`.
586571
///
587572
/// Required in order to paint text.
@@ -591,7 +576,7 @@ pub struct FontsImpl {
591576
definitions: FontDefinitions,
592577
atlas: Arc<Mutex<TextureAtlas>>,
593578
font_impl_cache: FontImplCache,
594-
sized_family: ahash::HashMap<(HashableF32, FontFamily), Font>,
579+
sized_family: ahash::HashMap<(OrderedFloat<f32>, FontFamily), Font>,
595580
}
596581

597582
impl FontsImpl {
@@ -641,7 +626,7 @@ impl FontsImpl {
641626
let FontId { size, family } = font_id;
642627

643628
self.sized_family
644-
.entry((HashableF32(*size), family.clone()))
629+
.entry((OrderedFloat(*size), family.clone()))
645630
.or_insert_with(|| {
646631
let fonts = &self.definitions.families.get(family);
647632
let fonts = fonts

crates/epaint/src/text/text_layout_types.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ impl std::hash::Hash for LayoutJob {
185185
text.hash(state);
186186
sections.hash(state);
187187
wrap.hash(state);
188-
crate::f32_hash(state, *first_row_min_height);
188+
emath::OrderedFloat(*first_row_min_height).hash(state);
189189
break_on_newline.hash(state);
190190
halign.hash(state);
191191
justify.hash(state);
@@ -214,7 +214,7 @@ impl std::hash::Hash for LayoutSection {
214214
byte_range,
215215
format,
216216
} = self;
217-
crate::f32_hash(state, *leading_space);
217+
OrderedFloat(*leading_space).hash(state);
218218
byte_range.hash(state);
219219
format.hash(state);
220220
}
@@ -293,9 +293,9 @@ impl std::hash::Hash for TextFormat {
293293
valign,
294294
} = self;
295295
font_id.hash(state);
296-
crate::f32_hash(state, *extra_letter_spacing);
296+
emath::OrderedFloat(*extra_letter_spacing).hash(state);
297297
if let Some(line_height) = *line_height {
298-
crate::f32_hash(state, line_height);
298+
emath::OrderedFloat(line_height).hash(state);
299299
}
300300
color.hash(state);
301301
background.hash(state);
@@ -375,7 +375,7 @@ impl std::hash::Hash for TextWrapping {
375375
break_anywhere,
376376
overflow_character,
377377
} = self;
378-
crate::f32_hash(state, *max_width);
378+
emath::OrderedFloat(*max_width).hash(state);
379379
max_rows.hash(state);
380380
break_anywhere.hash(state);
381381
overflow_character.hash(state);

crates/epaint/src/util/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
mod ordered_float;
2-
3-
pub use ordered_float::*;
1+
#[deprecated = "Use emath::OrderedFloat instead"]
2+
pub use emath::OrderedFloat;
43

54
/// Hash the given value with a predictable hasher.
65
#[inline]

0 commit comments

Comments
 (0)