/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ordered-float-4.6.0/src/lib.rs
Line | Count | Source |
1 | | #![no_std] |
2 | | #![cfg_attr(test, deny(warnings))] |
3 | | #![deny(missing_docs)] |
4 | | #![allow(clippy::derive_partial_eq_without_eq)] |
5 | | |
6 | | //! Wrappers for total order on Floats. See the [`OrderedFloat`] and [`NotNan`] docs for details. |
7 | | |
8 | | #[cfg(feature = "std")] |
9 | | extern crate std; |
10 | | #[cfg(feature = "std")] |
11 | | use std::error::Error; |
12 | | |
13 | | use core::borrow::Borrow; |
14 | | use core::cmp::Ordering; |
15 | | use core::convert::TryFrom; |
16 | | use core::fmt; |
17 | | use core::hash::{Hash, Hasher}; |
18 | | use core::iter::{Product, Sum}; |
19 | | use core::num::FpCategory; |
20 | | use core::ops::{ |
21 | | Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, |
22 | | SubAssign, |
23 | | }; |
24 | | use core::str::FromStr; |
25 | | |
26 | | pub use num_traits::float::FloatCore; |
27 | | use num_traits::{ |
28 | | AsPrimitive, Bounded, FloatConst, FromPrimitive, Num, NumCast, One, Signed, ToPrimitive, Zero, |
29 | | }; |
30 | | #[cfg(any(feature = "std", feature = "libm"))] |
31 | | pub use num_traits::{Float, Pow}; |
32 | | |
33 | | #[cfg(feature = "rand")] |
34 | | pub use impl_rand::{UniformNotNan, UniformOrdered}; |
35 | | |
36 | | // masks for the parts of the IEEE 754 float |
37 | | const SIGN_MASK: u64 = 0x8000000000000000u64; |
38 | | const EXP_MASK: u64 = 0x7ff0000000000000u64; |
39 | | const MAN_MASK: u64 = 0x000fffffffffffffu64; |
40 | | |
41 | | // canonical raw bit patterns (for hashing) |
42 | | const CANONICAL_NAN_BITS: u64 = 0x7ff8000000000000u64; |
43 | | |
44 | | #[inline(always)] |
45 | 0 | fn canonicalize_signed_zero<T: FloatCore>(x: T) -> T { |
46 | | // -0.0 + 0.0 == +0.0 under IEEE754 roundTiesToEven rounding mode, |
47 | | // which Rust guarantees. Thus by adding a positive zero we |
48 | | // canonicalize signed zero without any branches in one instruction. |
49 | 0 | x + T::zero() |
50 | 0 | } |
51 | | |
52 | | /// A wrapper around floats providing implementations of `Eq`, `Ord`, and `Hash`. |
53 | | /// |
54 | | /// NaN is sorted as *greater* than all other values and *equal* |
55 | | /// to itself, in contradiction with the IEEE standard. |
56 | | /// |
57 | | /// ``` |
58 | | /// use ordered_float::OrderedFloat; |
59 | | /// use std::f32::NAN; |
60 | | /// |
61 | | /// let mut v = [OrderedFloat(NAN), OrderedFloat(2.0), OrderedFloat(1.0)]; |
62 | | /// v.sort(); |
63 | | /// assert_eq!(v, [OrderedFloat(1.0), OrderedFloat(2.0), OrderedFloat(NAN)]); |
64 | | /// ``` |
65 | | /// |
66 | | /// Because `OrderedFloat` implements `Ord` and `Eq`, it can be used as a key in a `HashSet`, |
67 | | /// `HashMap`, `BTreeMap`, or `BTreeSet` (unlike the primitive `f32` or `f64` types): |
68 | | /// |
69 | | /// ``` |
70 | | /// # use ordered_float::OrderedFloat; |
71 | | /// # use std::collections::HashSet; |
72 | | /// # use std::f32::NAN; |
73 | | /// let mut s: HashSet<OrderedFloat<f32>> = HashSet::new(); |
74 | | /// s.insert(OrderedFloat(NAN)); |
75 | | /// assert!(s.contains(&OrderedFloat(NAN))); |
76 | | /// ``` |
77 | | /// |
78 | | /// Some non-identical values are still considered equal by the [`PartialEq`] implementation, |
79 | | /// and will therefore also be considered equal by maps, sets, and the `==` operator: |
80 | | /// |
81 | | /// * `-0.0` and `+0.0` are considered equal. |
82 | | /// This different sign may show up in printing, or when dividing by zero (the sign of the zero |
83 | | /// becomes the sign of the resulting infinity). |
84 | | /// * All NaN values are considered equal, even though they may have different |
85 | | /// [bits](https://doc.rust-lang.org/std/primitive.f64.html#method.to_bits), and therefore |
86 | | /// different [sign](https://doc.rust-lang.org/std/primitive.f64.html#method.is_sign_positive), |
87 | | /// signaling/quiet status, and NaN payload bits. |
88 | | /// |
89 | | /// Therefore, `OrderedFloat` may be unsuitable for use as a key in interning and memoization |
90 | | /// applications which require equal results from equal inputs, unless these cases make no |
91 | | /// difference or are canonicalized before insertion. |
92 | | /// |
93 | | /// # Representation |
94 | | /// |
95 | | /// `OrderedFloat` has `#[repr(transparent)]` and permits any value, so it is sound to use |
96 | | /// [transmute](core::mem::transmute) or pointer casts to convert between any type `T` and |
97 | | /// `OrderedFloat<T>`. |
98 | | /// However, consider using [`bytemuck`] as a safe alternative if possible. |
99 | | /// |
100 | | #[cfg_attr( |
101 | | not(feature = "bytemuck"), |
102 | | doc = "[`bytemuck`]: https://docs.rs/bytemuck/1/" |
103 | | )] |
104 | | #[derive(Default, Clone, Copy)] |
105 | | #[repr(transparent)] |
106 | | pub struct OrderedFloat<T>(pub T); |
107 | | |
108 | | #[cfg(feature = "derive-visitor")] |
109 | | mod impl_derive_visitor { |
110 | | use crate::OrderedFloat; |
111 | | use derive_visitor::{Drive, DriveMut, Event, Visitor, VisitorMut}; |
112 | | |
113 | | impl<T: 'static> Drive for OrderedFloat<T> { |
114 | | fn drive<V: Visitor>(&self, visitor: &mut V) { |
115 | | visitor.visit(self, Event::Enter); |
116 | | visitor.visit(self, Event::Exit); |
117 | | } |
118 | | } |
119 | | |
120 | | impl<T: 'static> DriveMut for OrderedFloat<T> { |
121 | | fn drive_mut<V: VisitorMut>(&mut self, visitor: &mut V) { |
122 | | visitor.visit(self, Event::Enter); |
123 | | visitor.visit(self, Event::Exit); |
124 | | } |
125 | | } |
126 | | |
127 | | #[test] |
128 | | pub fn test_derive_visitor() { |
129 | | #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] |
130 | | pub enum Literal { |
131 | | Null, |
132 | | Float(OrderedFloat<f64>), |
133 | | } |
134 | | |
135 | | #[derive(Visitor, VisitorMut)] |
136 | | #[visitor(Literal(enter))] |
137 | | struct FloatExpr(bool); |
138 | | |
139 | | impl FloatExpr { |
140 | | fn enter_literal(&mut self, lit: &Literal) { |
141 | | if let Literal::Float(_) = lit { |
142 | | self.0 = true; |
143 | | } |
144 | | } |
145 | | } |
146 | | |
147 | | assert!({ |
148 | | let mut visitor = FloatExpr(false); |
149 | | Literal::Null.drive(&mut visitor); |
150 | | !visitor.0 |
151 | | }); |
152 | | |
153 | | assert!({ |
154 | | let mut visitor = FloatExpr(false); |
155 | | Literal::Null.drive_mut(&mut visitor); |
156 | | !visitor.0 |
157 | | }); |
158 | | |
159 | | assert!({ |
160 | | let mut visitor = FloatExpr(false); |
161 | | Literal::Float(OrderedFloat(0.0)).drive(&mut visitor); |
162 | | visitor.0 |
163 | | }); |
164 | | |
165 | | assert!({ |
166 | | let mut visitor = FloatExpr(false); |
167 | | Literal::Float(OrderedFloat(0.0)).drive_mut(&mut visitor); |
168 | | visitor.0 |
169 | | }); |
170 | | } |
171 | | } |
172 | | |
173 | | #[cfg(feature = "num-cmp")] |
174 | | mod impl_num_cmp { |
175 | | use super::OrderedFloat; |
176 | | use core::cmp::Ordering; |
177 | | use num_cmp::NumCmp; |
178 | | use num_traits::float::FloatCore; |
179 | | |
180 | | impl<T, U> NumCmp<U> for OrderedFloat<T> |
181 | | where |
182 | | T: FloatCore + NumCmp<U>, |
183 | | U: Copy, |
184 | | { |
185 | | fn num_cmp(self, other: U) -> Option<Ordering> { |
186 | | NumCmp::num_cmp(self.0, other) |
187 | | } |
188 | | |
189 | | fn num_eq(self, other: U) -> bool { |
190 | | NumCmp::num_eq(self.0, other) |
191 | | } |
192 | | |
193 | | fn num_ne(self, other: U) -> bool { |
194 | | NumCmp::num_ne(self.0, other) |
195 | | } |
196 | | |
197 | | fn num_lt(self, other: U) -> bool { |
198 | | NumCmp::num_lt(self.0, other) |
199 | | } |
200 | | |
201 | | fn num_gt(self, other: U) -> bool { |
202 | | NumCmp::num_gt(self.0, other) |
203 | | } |
204 | | |
205 | | fn num_le(self, other: U) -> bool { |
206 | | NumCmp::num_le(self.0, other) |
207 | | } |
208 | | |
209 | | fn num_ge(self, other: U) -> bool { |
210 | | NumCmp::num_ge(self.0, other) |
211 | | } |
212 | | } |
213 | | |
214 | | #[test] |
215 | | pub fn test_num_cmp() { |
216 | | let f = OrderedFloat(1.0); |
217 | | |
218 | | assert_eq!(NumCmp::num_cmp(f, 1.0), Some(Ordering::Equal)); |
219 | | assert_eq!(NumCmp::num_cmp(f, -1.0), Some(Ordering::Greater)); |
220 | | assert_eq!(NumCmp::num_cmp(f, 2.0), Some(Ordering::Less)); |
221 | | |
222 | | assert!(NumCmp::num_eq(f, 1)); |
223 | | assert!(NumCmp::num_ne(f, -1)); |
224 | | assert!(NumCmp::num_lt(f, 100)); |
225 | | assert!(NumCmp::num_gt(f, 0)); |
226 | | assert!(NumCmp::num_le(f, 1)); |
227 | | assert!(NumCmp::num_le(f, 2)); |
228 | | assert!(NumCmp::num_ge(f, 1)); |
229 | | assert!(NumCmp::num_ge(f, -1)); |
230 | | } |
231 | | } |
232 | | |
233 | | impl<T: FloatCore> OrderedFloat<T> { |
234 | | /// Get the value out. |
235 | | #[inline] |
236 | 0 | pub fn into_inner(self) -> T { |
237 | 0 | self.0 |
238 | 0 | } |
239 | | } |
240 | | |
241 | | impl<T: FloatCore> AsRef<T> for OrderedFloat<T> { |
242 | | #[inline] |
243 | 0 | fn as_ref(&self) -> &T { |
244 | 0 | &self.0 |
245 | 0 | } |
246 | | } |
247 | | |
248 | | impl<T: FloatCore> AsMut<T> for OrderedFloat<T> { |
249 | | #[inline] |
250 | 0 | fn as_mut(&mut self) -> &mut T { |
251 | 0 | &mut self.0 |
252 | 0 | } |
253 | | } |
254 | | |
255 | | impl<'a, T: FloatCore> From<&'a T> for &'a OrderedFloat<T> { |
256 | | #[inline] |
257 | 0 | fn from(t: &'a T) -> &'a OrderedFloat<T> { |
258 | | // Safety: OrderedFloat is #[repr(transparent)] and has no invalid values. |
259 | 0 | unsafe { &*(t as *const T as *const OrderedFloat<T>) } |
260 | 0 | } |
261 | | } |
262 | | |
263 | | impl<'a, T: FloatCore> From<&'a mut T> for &'a mut OrderedFloat<T> { |
264 | | #[inline] |
265 | 0 | fn from(t: &'a mut T) -> &'a mut OrderedFloat<T> { |
266 | | // Safety: OrderedFloat is #[repr(transparent)] and has no invalid values. |
267 | 0 | unsafe { &mut *(t as *mut T as *mut OrderedFloat<T>) } |
268 | 0 | } |
269 | | } |
270 | | |
271 | | impl<T: FloatCore> PartialOrd for OrderedFloat<T> { |
272 | | #[inline] |
273 | 0 | fn partial_cmp(&self, other: &Self) -> Option<Ordering> { |
274 | 0 | Some(self.cmp(other)) |
275 | 0 | } |
276 | | |
277 | | #[inline] |
278 | 0 | fn lt(&self, other: &Self) -> bool { |
279 | 0 | !self.ge(other) |
280 | 0 | } |
281 | | |
282 | | #[inline] |
283 | 0 | fn le(&self, other: &Self) -> bool { |
284 | 0 | other.ge(self) |
285 | 0 | } |
286 | | |
287 | | #[inline] |
288 | 0 | fn gt(&self, other: &Self) -> bool { |
289 | 0 | !other.ge(self) |
290 | 0 | } |
291 | | |
292 | | #[inline] |
293 | 0 | fn ge(&self, other: &Self) -> bool { |
294 | | // We consider all NaNs equal, and NaN is the largest possible |
295 | | // value. Thus if self is NaN we always return true. Otherwise |
296 | | // self >= other is correct. If other is also not NaN it is trivially |
297 | | // correct, and if it is we note that nothing can be greater or |
298 | | // equal to NaN except NaN itself, which we already handled earlier. |
299 | 0 | self.0.is_nan() | (self.0 >= other.0) |
300 | 0 | } |
301 | | } |
302 | | |
303 | | impl<T: FloatCore> Ord for OrderedFloat<T> { |
304 | | #[inline] |
305 | 0 | fn cmp(&self, other: &Self) -> Ordering { |
306 | | #[allow(clippy::comparison_chain)] |
307 | 0 | if self < other { |
308 | 0 | Ordering::Less |
309 | 0 | } else if self > other { |
310 | 0 | Ordering::Greater |
311 | | } else { |
312 | 0 | Ordering::Equal |
313 | | } |
314 | 0 | } |
315 | | } |
316 | | |
317 | | impl<T: FloatCore> PartialEq for OrderedFloat<T> { |
318 | | #[inline] |
319 | 11.5k | fn eq(&self, other: &OrderedFloat<T>) -> bool { |
320 | 11.5k | if self.0.is_nan() { |
321 | 142 | other.0.is_nan() |
322 | | } else { |
323 | 11.3k | self.0 == other.0 |
324 | | } |
325 | 11.5k | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::cmp::PartialEq>::eq <ordered_float::OrderedFloat<f64> as core::cmp::PartialEq>::eq Line | Count | Source | 319 | 6.30k | fn eq(&self, other: &OrderedFloat<T>) -> bool { | 320 | 6.30k | if self.0.is_nan() { | 321 | 71 | other.0.is_nan() | 322 | | } else { | 323 | 6.23k | self.0 == other.0 | 324 | | } | 325 | 6.30k | } |
<ordered_float::OrderedFloat<f64> as core::cmp::PartialEq>::eq Line | Count | Source | 319 | 5.23k | fn eq(&self, other: &OrderedFloat<T>) -> bool { | 320 | 5.23k | if self.0.is_nan() { | 321 | 71 | other.0.is_nan() | 322 | | } else { | 323 | 5.16k | self.0 == other.0 | 324 | | } | 325 | 5.23k | } |
|
326 | | } |
327 | | |
328 | | impl<T: FloatCore> PartialEq<T> for OrderedFloat<T> { |
329 | | #[inline] |
330 | 0 | fn eq(&self, other: &T) -> bool { |
331 | 0 | self.0 == *other |
332 | 0 | } |
333 | | } |
334 | | |
335 | | impl<T: FloatCore> Hash for OrderedFloat<T> { |
336 | 0 | fn hash<H: Hasher>(&self, state: &mut H) { |
337 | 0 | let bits = if self.is_nan() { |
338 | 0 | CANONICAL_NAN_BITS |
339 | | } else { |
340 | 0 | raw_double_bits(&canonicalize_signed_zero(self.0)) |
341 | | }; |
342 | | |
343 | 0 | bits.hash(state) |
344 | 0 | } |
345 | | } |
346 | | |
347 | | impl<T: fmt::Debug> fmt::Debug for OrderedFloat<T> { |
348 | | #[inline] |
349 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
350 | 0 | self.0.fmt(f) |
351 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::fmt::Debug>::fmt Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as core::fmt::Debug>::fmt Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as core::fmt::Debug>::fmt |
352 | | } |
353 | | |
354 | | impl<T: FloatCore + fmt::Display> fmt::Display for OrderedFloat<T> { |
355 | | #[inline] |
356 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
357 | 0 | self.0.fmt(f) |
358 | 0 | } |
359 | | } |
360 | | |
361 | | impl<T: FloatCore + fmt::LowerExp> fmt::LowerExp for OrderedFloat<T> { |
362 | | #[inline] |
363 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
364 | 0 | self.0.fmt(f) |
365 | 0 | } |
366 | | } |
367 | | |
368 | | impl<T: FloatCore + fmt::UpperExp> fmt::UpperExp for OrderedFloat<T> { |
369 | | #[inline] |
370 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
371 | 0 | self.0.fmt(f) |
372 | 0 | } |
373 | | } |
374 | | |
375 | | impl From<OrderedFloat<f32>> for f32 { |
376 | | #[inline] |
377 | 0 | fn from(f: OrderedFloat<f32>) -> f32 { |
378 | 0 | f.0 |
379 | 0 | } |
380 | | } |
381 | | |
382 | | impl From<OrderedFloat<f64>> for f64 { |
383 | | #[inline] |
384 | 33.4k | fn from(f: OrderedFloat<f64>) -> f64 { |
385 | 33.4k | f.0 |
386 | 33.4k | } <f64 as core::convert::From<ordered_float::OrderedFloat<f64>>>::from Line | Count | Source | 384 | 33.4k | fn from(f: OrderedFloat<f64>) -> f64 { | 385 | 33.4k | f.0 | 386 | 33.4k | } |
Unexecuted instantiation: <f64 as core::convert::From<ordered_float::OrderedFloat<f64>>>::from |
387 | | } |
388 | | |
389 | | impl<T: FloatCore> From<T> for OrderedFloat<T> { |
390 | | #[inline] |
391 | 326k | fn from(val: T) -> Self { |
392 | 326k | OrderedFloat(val) |
393 | 326k | } <ordered_float::OrderedFloat<f64> as core::convert::From<f64>>::from Line | Count | Source | 391 | 326k | fn from(val: T) -> Self { | 392 | 326k | OrderedFloat(val) | 393 | 326k | } |
Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as core::convert::From<f32>>::from |
394 | | } |
395 | | |
396 | | impl From<bool> for OrderedFloat<f32> { |
397 | 0 | fn from(val: bool) -> Self { |
398 | 0 | OrderedFloat(val as u8 as f32) |
399 | 0 | } |
400 | | } |
401 | | |
402 | | impl From<bool> for OrderedFloat<f64> { |
403 | 0 | fn from(val: bool) -> Self { |
404 | 0 | OrderedFloat(val as u8 as f64) |
405 | 0 | } |
406 | | } |
407 | | |
408 | | macro_rules! impl_ordered_float_from { |
409 | | ($dst:ty, $src:ty) => { |
410 | | impl From<$src> for OrderedFloat<$dst> { |
411 | 0 | fn from(val: $src) -> Self { |
412 | 0 | OrderedFloat(val.into()) |
413 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as core::convert::From<i8>>::from Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as core::convert::From<i16>>::from Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as core::convert::From<i32>>::from Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as core::convert::From<u8>>::from Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as core::convert::From<u16>>::from Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as core::convert::From<u32>>::from Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as core::convert::From<i8>>::from Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as core::convert::From<i16>>::from Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as core::convert::From<u8>>::from Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as core::convert::From<u16>>::from |
414 | | } |
415 | | }; |
416 | | } |
417 | | impl_ordered_float_from! {f64, i8} |
418 | | impl_ordered_float_from! {f64, i16} |
419 | | impl_ordered_float_from! {f64, i32} |
420 | | impl_ordered_float_from! {f64, u8} |
421 | | impl_ordered_float_from! {f64, u16} |
422 | | impl_ordered_float_from! {f64, u32} |
423 | | impl_ordered_float_from! {f32, i8} |
424 | | impl_ordered_float_from! {f32, i16} |
425 | | impl_ordered_float_from! {f32, u8} |
426 | | impl_ordered_float_from! {f32, u16} |
427 | | |
428 | | impl<T: FloatCore> Deref for OrderedFloat<T> { |
429 | | type Target = T; |
430 | | |
431 | | #[inline] |
432 | 0 | fn deref(&self) -> &Self::Target { |
433 | 0 | &self.0 |
434 | 0 | } |
435 | | } |
436 | | |
437 | | impl<T: FloatCore> DerefMut for OrderedFloat<T> { |
438 | | #[inline] |
439 | 0 | fn deref_mut(&mut self) -> &mut Self::Target { |
440 | 0 | &mut self.0 |
441 | 0 | } |
442 | | } |
443 | | |
444 | | impl<T: FloatCore> Eq for OrderedFloat<T> {} |
445 | | |
446 | | macro_rules! impl_ordered_float_binop { |
447 | | ($imp:ident, $method:ident, $assign_imp:ident, $assign_method:ident) => { |
448 | | impl<T: $imp> $imp for OrderedFloat<T> { |
449 | | type Output = OrderedFloat<T::Output>; |
450 | | |
451 | | #[inline] |
452 | 0 | fn $method(self, other: Self) -> Self::Output { |
453 | 0 | OrderedFloat((self.0).$method(other.0)) |
454 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Add>::add Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Div>::div Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Rem>::rem |
455 | | } |
456 | | |
457 | | // Work around for: https://github.com/reem/rust-ordered-float/issues/91 |
458 | | impl<'a, T: $imp + Copy> $imp<Self> for &'a OrderedFloat<T> { |
459 | | type Output = OrderedFloat<T::Output>; |
460 | | |
461 | | #[inline] |
462 | 0 | fn $method(self, other: Self) -> Self::Output { |
463 | 0 | OrderedFloat((self.0).$method(other.0)) |
464 | 0 | } Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Add>::add Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Div>::div Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Rem>::rem |
465 | | } |
466 | | |
467 | | impl<T: $imp> $imp<T> for OrderedFloat<T> { |
468 | | type Output = OrderedFloat<T::Output>; |
469 | | |
470 | | #[inline] |
471 | 0 | fn $method(self, other: T) -> Self::Output { |
472 | 0 | OrderedFloat((self.0).$method(other)) |
473 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Sub<_>>::sub Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Mul<_>>::mul Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Add<_>>::add Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Div<_>>::div Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Rem<_>>::rem |
474 | | } |
475 | | |
476 | | impl<'a, T> $imp<&'a T> for OrderedFloat<T> |
477 | | where |
478 | | T: $imp<&'a T>, |
479 | | { |
480 | | type Output = OrderedFloat<<T as $imp<&'a T>>::Output>; |
481 | | |
482 | | #[inline] |
483 | 0 | fn $method(self, other: &'a T) -> Self::Output { |
484 | 0 | OrderedFloat((self.0).$method(other)) |
485 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Sub<&_>>::sub Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Mul<&_>>::mul Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Add<&_>>::add Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Div<&_>>::div Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Rem<&_>>::rem |
486 | | } |
487 | | |
488 | | impl<'a, T> $imp<&'a Self> for OrderedFloat<T> |
489 | | where |
490 | | T: $imp<&'a T>, |
491 | | { |
492 | | type Output = OrderedFloat<<T as $imp<&'a T>>::Output>; |
493 | | |
494 | | #[inline] |
495 | 0 | fn $method(self, other: &'a Self) -> Self::Output { |
496 | 0 | OrderedFloat((self.0).$method(&other.0)) |
497 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Sub<&ordered_float::OrderedFloat<_>>>::sub Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Mul<&ordered_float::OrderedFloat<_>>>::mul Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Add<&ordered_float::OrderedFloat<_>>>::add Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Div<&ordered_float::OrderedFloat<_>>>::div Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::Rem<&ordered_float::OrderedFloat<_>>>::rem |
498 | | } |
499 | | |
500 | | impl<'a, T> $imp<OrderedFloat<T>> for &'a OrderedFloat<T> |
501 | | where |
502 | | &'a T: $imp<T>, |
503 | | { |
504 | | type Output = OrderedFloat<<&'a T as $imp<T>>::Output>; |
505 | | |
506 | | #[inline] |
507 | 0 | fn $method(self, other: OrderedFloat<T>) -> Self::Output { |
508 | 0 | OrderedFloat((self.0).$method(other.0)) |
509 | 0 | } Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Add<ordered_float::OrderedFloat<_>>>::add Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Sub<ordered_float::OrderedFloat<_>>>::sub Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Mul<ordered_float::OrderedFloat<_>>>::mul Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Div<ordered_float::OrderedFloat<_>>>::div Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Rem<ordered_float::OrderedFloat<_>>>::rem |
510 | | } |
511 | | |
512 | | impl<'a, T> $imp<T> for &'a OrderedFloat<T> |
513 | | where |
514 | | &'a T: $imp<T>, |
515 | | { |
516 | | type Output = OrderedFloat<<&'a T as $imp<T>>::Output>; |
517 | | |
518 | | #[inline] |
519 | 0 | fn $method(self, other: T) -> Self::Output { |
520 | 0 | OrderedFloat((self.0).$method(other)) |
521 | 0 | } Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Add<_>>::add Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Sub<_>>::sub Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Mul<_>>::mul Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Div<_>>::div Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Rem<_>>::rem |
522 | | } |
523 | | |
524 | | impl<'a, T> $imp<&'a T> for &'a OrderedFloat<T> |
525 | | where |
526 | | &'a T: $imp, |
527 | | { |
528 | | type Output = OrderedFloat<<&'a T as $imp>::Output>; |
529 | | |
530 | | #[inline] |
531 | 0 | fn $method(self, other: &'a T) -> Self::Output { |
532 | 0 | OrderedFloat((self.0).$method(other)) |
533 | 0 | } Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Add<&_>>::add Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Sub<&_>>::sub Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Mul<&_>>::mul Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Div<&_>>::div Unexecuted instantiation: <&ordered_float::OrderedFloat<_> as core::ops::arith::Rem<&_>>::rem |
534 | | } |
535 | | |
536 | | impl<T: $assign_imp> $assign_imp<T> for OrderedFloat<T> { |
537 | | #[inline] |
538 | 0 | fn $assign_method(&mut self, other: T) { |
539 | 0 | (self.0).$assign_method(other); |
540 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::AddAssign<_>>::add_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::SubAssign<_>>::sub_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::MulAssign<_>>::mul_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::DivAssign<_>>::div_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::RemAssign<_>>::rem_assign |
541 | | } |
542 | | |
543 | | impl<'a, T: $assign_imp<&'a T>> $assign_imp<&'a T> for OrderedFloat<T> { |
544 | | #[inline] |
545 | 0 | fn $assign_method(&mut self, other: &'a T) { |
546 | 0 | (self.0).$assign_method(other); |
547 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::AddAssign<&_>>::add_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::SubAssign<&_>>::sub_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::MulAssign<&_>>::mul_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::DivAssign<&_>>::div_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::RemAssign<&_>>::rem_assign |
548 | | } |
549 | | |
550 | | impl<T: $assign_imp> $assign_imp for OrderedFloat<T> { |
551 | | #[inline] |
552 | 0 | fn $assign_method(&mut self, other: Self) { |
553 | 0 | (self.0).$assign_method(other.0); |
554 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::RemAssign>::rem_assign |
555 | | } |
556 | | |
557 | | impl<'a, T: $assign_imp<&'a T>> $assign_imp<&'a Self> for OrderedFloat<T> { |
558 | | #[inline] |
559 | 0 | fn $assign_method(&mut self, other: &'a Self) { |
560 | 0 | (self.0).$assign_method(&other.0); |
561 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::AddAssign<&ordered_float::OrderedFloat<_>>>::add_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::SubAssign<&ordered_float::OrderedFloat<_>>>::sub_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::MulAssign<&ordered_float::OrderedFloat<_>>>::mul_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::DivAssign<&ordered_float::OrderedFloat<_>>>::div_assign Unexecuted instantiation: <ordered_float::OrderedFloat<_> as core::ops::arith::RemAssign<&ordered_float::OrderedFloat<_>>>::rem_assign |
562 | | } |
563 | | }; |
564 | | } |
565 | | |
566 | | impl_ordered_float_binop! {Add, add, AddAssign, add_assign} |
567 | | impl_ordered_float_binop! {Sub, sub, SubAssign, sub_assign} |
568 | | impl_ordered_float_binop! {Mul, mul, MulAssign, mul_assign} |
569 | | impl_ordered_float_binop! {Div, div, DivAssign, div_assign} |
570 | | impl_ordered_float_binop! {Rem, rem, RemAssign, rem_assign} |
571 | | |
572 | | macro_rules! impl_ordered_float_pow { |
573 | | ($inner:ty, $rhs:ty) => { |
574 | | #[cfg(any(feature = "std", feature = "libm"))] |
575 | | impl Pow<$rhs> for OrderedFloat<$inner> { |
576 | | type Output = OrderedFloat<$inner>; |
577 | | #[inline] |
578 | 0 | fn pow(self, rhs: $rhs) -> OrderedFloat<$inner> { |
579 | 0 | OrderedFloat(<$inner>::pow(self.0, rhs)) |
580 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<u8>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<u16>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<i32>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<i8>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<i16>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<u8>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<u16>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<i8>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<i16>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<i32>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<f32>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<f32>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<f64>>::pow |
581 | | } |
582 | | |
583 | | #[cfg(any(feature = "std", feature = "libm"))] |
584 | | impl<'a> Pow<&'a $rhs> for OrderedFloat<$inner> { |
585 | | type Output = OrderedFloat<$inner>; |
586 | | #[inline] |
587 | 0 | fn pow(self, rhs: &'a $rhs) -> OrderedFloat<$inner> { |
588 | 0 | OrderedFloat(<$inner>::pow(self.0, *rhs)) |
589 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&u8>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&u16>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&i32>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&i8>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&i16>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&u8>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&i8>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&i16>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&u16>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&i32>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&f32>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&f32>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&f64>>::pow |
590 | | } |
591 | | |
592 | | #[cfg(any(feature = "std", feature = "libm"))] |
593 | | impl<'a> Pow<$rhs> for &'a OrderedFloat<$inner> { |
594 | | type Output = OrderedFloat<$inner>; |
595 | | #[inline] |
596 | 0 | fn pow(self, rhs: $rhs) -> OrderedFloat<$inner> { |
597 | 0 | OrderedFloat(<$inner>::pow(self.0, rhs)) |
598 | 0 | } Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<u8>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<u16>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<i32>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<i8>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<i16>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<u8>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<i8>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<i16>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<u16>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<i32>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<f32>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<f32>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<f64>>::pow |
599 | | } |
600 | | |
601 | | #[cfg(any(feature = "std", feature = "libm"))] |
602 | | impl<'a, 'b> Pow<&'a $rhs> for &'b OrderedFloat<$inner> { |
603 | | type Output = OrderedFloat<$inner>; |
604 | | #[inline] |
605 | 0 | fn pow(self, rhs: &'a $rhs) -> OrderedFloat<$inner> { |
606 | 0 | OrderedFloat(<$inner>::pow(self.0, *rhs)) |
607 | 0 | } Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&i16>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&u8>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&u16>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&i32>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&i8>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&i16>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&u8>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&i8>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&u16>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&i32>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&f32>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&f32>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&f64>>::pow |
608 | | } |
609 | | }; |
610 | | } |
611 | | |
612 | | impl_ordered_float_pow! {f32, i8} |
613 | | impl_ordered_float_pow! {f32, i16} |
614 | | impl_ordered_float_pow! {f32, u8} |
615 | | impl_ordered_float_pow! {f32, u16} |
616 | | impl_ordered_float_pow! {f32, i32} |
617 | | impl_ordered_float_pow! {f64, i8} |
618 | | impl_ordered_float_pow! {f64, i16} |
619 | | impl_ordered_float_pow! {f64, u8} |
620 | | impl_ordered_float_pow! {f64, u16} |
621 | | impl_ordered_float_pow! {f64, i32} |
622 | | impl_ordered_float_pow! {f32, f32} |
623 | | impl_ordered_float_pow! {f64, f32} |
624 | | impl_ordered_float_pow! {f64, f64} |
625 | | |
626 | | macro_rules! impl_ordered_float_self_pow { |
627 | | ($base:ty, $exp:ty) => { |
628 | | #[cfg(any(feature = "std", feature = "libm"))] |
629 | | impl Pow<OrderedFloat<$exp>> for OrderedFloat<$base> { |
630 | | type Output = OrderedFloat<$base>; |
631 | | #[inline] |
632 | 0 | fn pow(self, rhs: OrderedFloat<$exp>) -> OrderedFloat<$base> { |
633 | 0 | OrderedFloat(<$base>::pow(self.0, rhs.0)) |
634 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<ordered_float::OrderedFloat<f32>>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<ordered_float::OrderedFloat<f32>>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<ordered_float::OrderedFloat<f64>>>::pow |
635 | | } |
636 | | |
637 | | #[cfg(any(feature = "std", feature = "libm"))] |
638 | | impl<'a> Pow<&'a OrderedFloat<$exp>> for OrderedFloat<$base> { |
639 | | type Output = OrderedFloat<$base>; |
640 | | #[inline] |
641 | 0 | fn pow(self, rhs: &'a OrderedFloat<$exp>) -> OrderedFloat<$base> { |
642 | 0 | OrderedFloat(<$base>::pow(self.0, rhs.0)) |
643 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&ordered_float::OrderedFloat<f32>>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&ordered_float::OrderedFloat<f32>>>::pow Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&ordered_float::OrderedFloat<f64>>>::pow |
644 | | } |
645 | | |
646 | | #[cfg(any(feature = "std", feature = "libm"))] |
647 | | impl<'a> Pow<OrderedFloat<$exp>> for &'a OrderedFloat<$base> { |
648 | | type Output = OrderedFloat<$base>; |
649 | | #[inline] |
650 | 0 | fn pow(self, rhs: OrderedFloat<$exp>) -> OrderedFloat<$base> { |
651 | 0 | OrderedFloat(<$base>::pow(self.0, rhs.0)) |
652 | 0 | } Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<ordered_float::OrderedFloat<f32>>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<ordered_float::OrderedFloat<f32>>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<ordered_float::OrderedFloat<f64>>>::pow |
653 | | } |
654 | | |
655 | | #[cfg(any(feature = "std", feature = "libm"))] |
656 | | impl<'a, 'b> Pow<&'a OrderedFloat<$exp>> for &'b OrderedFloat<$base> { |
657 | | type Output = OrderedFloat<$base>; |
658 | | #[inline] |
659 | 0 | fn pow(self, rhs: &'a OrderedFloat<$exp>) -> OrderedFloat<$base> { |
660 | 0 | OrderedFloat(<$base>::pow(self.0, rhs.0)) |
661 | 0 | } Unexecuted instantiation: <&ordered_float::OrderedFloat<f32> as num_traits::pow::Pow<&ordered_float::OrderedFloat<f32>>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&ordered_float::OrderedFloat<f32>>>::pow Unexecuted instantiation: <&ordered_float::OrderedFloat<f64> as num_traits::pow::Pow<&ordered_float::OrderedFloat<f64>>>::pow |
662 | | } |
663 | | }; |
664 | | } |
665 | | |
666 | | impl_ordered_float_self_pow! {f32, f32} |
667 | | impl_ordered_float_self_pow! {f64, f32} |
668 | | impl_ordered_float_self_pow! {f64, f64} |
669 | | |
670 | | /// Adds a float directly. |
671 | | impl<T: FloatCore + Sum> Sum for OrderedFloat<T> { |
672 | 0 | fn sum<I: Iterator<Item = OrderedFloat<T>>>(iter: I) -> Self { |
673 | 0 | OrderedFloat(iter.map(|v| v.0).sum()) |
674 | 0 | } |
675 | | } |
676 | | |
677 | | impl<'a, T: FloatCore + Sum + 'a> Sum<&'a OrderedFloat<T>> for OrderedFloat<T> { |
678 | | #[inline] |
679 | 0 | fn sum<I: Iterator<Item = &'a OrderedFloat<T>>>(iter: I) -> Self { |
680 | 0 | iter.cloned().sum() |
681 | 0 | } |
682 | | } |
683 | | |
684 | | impl<T: FloatCore + Product> Product for OrderedFloat<T> { |
685 | 0 | fn product<I: Iterator<Item = OrderedFloat<T>>>(iter: I) -> Self { |
686 | 0 | OrderedFloat(iter.map(|v| v.0).product()) |
687 | 0 | } |
688 | | } |
689 | | |
690 | | impl<'a, T: FloatCore + Product + 'a> Product<&'a OrderedFloat<T>> for OrderedFloat<T> { |
691 | | #[inline] |
692 | 0 | fn product<I: Iterator<Item = &'a OrderedFloat<T>>>(iter: I) -> Self { |
693 | 0 | iter.cloned().product() |
694 | 0 | } |
695 | | } |
696 | | |
697 | | impl<T: FloatCore + Signed> Signed for OrderedFloat<T> { |
698 | | #[inline] |
699 | 0 | fn abs(&self) -> Self { |
700 | 0 | OrderedFloat(self.0.abs()) |
701 | 0 | } |
702 | | |
703 | 0 | fn abs_sub(&self, other: &Self) -> Self { |
704 | 0 | OrderedFloat(Signed::abs_sub(&self.0, &other.0)) |
705 | 0 | } |
706 | | |
707 | | #[inline] |
708 | 0 | fn signum(&self) -> Self { |
709 | 0 | OrderedFloat(self.0.signum()) |
710 | 0 | } |
711 | | #[inline] |
712 | 0 | fn is_positive(&self) -> bool { |
713 | 0 | self.0.is_positive() |
714 | 0 | } |
715 | | #[inline] |
716 | 0 | fn is_negative(&self) -> bool { |
717 | 0 | self.0.is_negative() |
718 | 0 | } |
719 | | } |
720 | | |
721 | | impl<T: Bounded> Bounded for OrderedFloat<T> { |
722 | | #[inline] |
723 | 0 | fn min_value() -> Self { |
724 | 0 | OrderedFloat(T::min_value()) |
725 | 0 | } |
726 | | |
727 | | #[inline] |
728 | 0 | fn max_value() -> Self { |
729 | 0 | OrderedFloat(T::max_value()) |
730 | 0 | } |
731 | | } |
732 | | |
733 | | impl<T: FromStr> FromStr for OrderedFloat<T> { |
734 | | type Err = T::Err; |
735 | | |
736 | | /// Convert a &str to `OrderedFloat`. Returns an error if the string fails to parse. |
737 | | /// |
738 | | /// ``` |
739 | | /// use ordered_float::OrderedFloat; |
740 | | /// |
741 | | /// assert!("-10".parse::<OrderedFloat<f32>>().is_ok()); |
742 | | /// assert!("abc".parse::<OrderedFloat<f32>>().is_err()); |
743 | | /// assert!("NaN".parse::<OrderedFloat<f32>>().is_ok()); |
744 | | /// ``` |
745 | 0 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
746 | 0 | T::from_str(s).map(OrderedFloat) |
747 | 0 | } |
748 | | } |
749 | | |
750 | | impl<T: Neg> Neg for OrderedFloat<T> { |
751 | | type Output = OrderedFloat<T::Output>; |
752 | | |
753 | | #[inline] |
754 | 0 | fn neg(self) -> Self::Output { |
755 | 0 | OrderedFloat(-self.0) |
756 | 0 | } |
757 | | } |
758 | | |
759 | | impl<'a, T> Neg for &'a OrderedFloat<T> |
760 | | where |
761 | | &'a T: Neg, |
762 | | { |
763 | | type Output = OrderedFloat<<&'a T as Neg>::Output>; |
764 | | |
765 | | #[inline] |
766 | 0 | fn neg(self) -> Self::Output { |
767 | 0 | OrderedFloat(-(&self.0)) |
768 | 0 | } |
769 | | } |
770 | | |
771 | | impl<T: Zero> Zero for OrderedFloat<T> { |
772 | | #[inline] |
773 | 0 | fn zero() -> Self { |
774 | 0 | OrderedFloat(T::zero()) |
775 | 0 | } |
776 | | |
777 | | #[inline] |
778 | 0 | fn is_zero(&self) -> bool { |
779 | 0 | self.0.is_zero() |
780 | 0 | } |
781 | | } |
782 | | |
783 | | impl<T: One> One for OrderedFloat<T> { |
784 | | #[inline] |
785 | 0 | fn one() -> Self { |
786 | 0 | OrderedFloat(T::one()) |
787 | 0 | } |
788 | | } |
789 | | |
790 | | impl<T: NumCast> NumCast for OrderedFloat<T> { |
791 | | #[inline] |
792 | 0 | fn from<F: ToPrimitive>(n: F) -> Option<Self> { |
793 | 0 | T::from(n).map(OrderedFloat) |
794 | 0 | } |
795 | | } |
796 | | |
797 | | macro_rules! impl_as_primitive { |
798 | | (@ (NotNan<$T: ty>) => $(#[$cfg:meta])* impl (NotNan<$U: ty>) ) => { |
799 | | $(#[$cfg])* |
800 | | impl AsPrimitive<NotNan<$U>> for NotNan<$T> { |
801 | 0 | #[inline] fn as_(self) -> NotNan<$U> { |
802 | | // Safety: `NotNan` guarantees that the value is not NaN. |
803 | 0 | unsafe {NotNan::new_unchecked(self.0 as $U) } |
804 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ |
805 | | } |
806 | | }; |
807 | | (@ ($T: ty) => $(#[$cfg:meta])* impl (NotNan<$U: ty>) ) => { |
808 | | $(#[$cfg])* |
809 | | impl AsPrimitive<NotNan<$U>> for $T { |
810 | 0 | #[inline] fn as_(self) -> NotNan<$U> { NotNan(self as $U) }Unexecuted instantiation: <u8 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <u8 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <i8 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <i8 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <u16 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <u16 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <i16 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <i16 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <u32 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <u32 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <i32 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <i32 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <u64 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <u64 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <i64 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <i64 as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <usize as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <usize as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ Unexecuted instantiation: <isize as num_traits::cast::AsPrimitive<ordered_float::NotNan<f32>>>::as_ Unexecuted instantiation: <isize as num_traits::cast::AsPrimitive<ordered_float::NotNan<f64>>>::as_ |
811 | | } |
812 | | }; |
813 | | (@ (NotNan<$T: ty>) => $(#[$cfg:meta])* impl ($U: ty) ) => { |
814 | | $(#[$cfg])* |
815 | | impl AsPrimitive<$U> for NotNan<$T> { |
816 | 0 | #[inline] fn as_(self) -> $U { self.0 as $U }Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<u8>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<u16>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<u32>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<u64>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<usize>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<i8>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<i16>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<i32>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<i64>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<isize>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<f32>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::cast::AsPrimitive<f64>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<u8>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<u16>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<u32>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<u64>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<usize>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<i8>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<i16>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<i32>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<i64>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<isize>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<f32>>::as_ Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::cast::AsPrimitive<f64>>::as_ |
817 | | } |
818 | | }; |
819 | | (@ (OrderedFloat<$T: ty>) => $(#[$cfg:meta])* impl (OrderedFloat<$U: ty>) ) => { |
820 | | $(#[$cfg])* |
821 | | impl AsPrimitive<OrderedFloat<$U>> for OrderedFloat<$T> { |
822 | 0 | #[inline] fn as_(self) -> OrderedFloat<$U> { OrderedFloat(self.0 as $U) }Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ |
823 | | } |
824 | | }; |
825 | | (@ ($T: ty) => $(#[$cfg:meta])* impl (OrderedFloat<$U: ty>) ) => { |
826 | | $(#[$cfg])* |
827 | | impl AsPrimitive<OrderedFloat<$U>> for $T { |
828 | 0 | #[inline] fn as_(self) -> OrderedFloat<$U> { OrderedFloat(self as $U) }Unexecuted instantiation: <u8 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <u8 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <i8 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <i8 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <u16 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <u16 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <i16 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <i16 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <u32 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <u32 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <i32 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <i32 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <u64 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <u64 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <i64 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <i64 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <usize as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <usize as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <isize as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <isize as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <f32 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <f32 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ Unexecuted instantiation: <f64 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f32>>>::as_ Unexecuted instantiation: <f64 as num_traits::cast::AsPrimitive<ordered_float::OrderedFloat<f64>>>::as_ |
829 | | } |
830 | | }; |
831 | | (@ (OrderedFloat<$T: ty>) => $(#[$cfg:meta])* impl ($U: ty) ) => { |
832 | | $(#[$cfg])* |
833 | | impl AsPrimitive<$U> for OrderedFloat<$T> { |
834 | 0 | #[inline] fn as_(self) -> $U { self.0 as $U }Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<u64>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<usize>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<i8>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<i16>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<i32>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<i64>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<isize>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<f32>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<f64>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<u8>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<u16>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<u32>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<u64>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<usize>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<i8>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<i16>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<i32>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<i64>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<isize>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<f32>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as num_traits::cast::AsPrimitive<f64>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<u8>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<u16>>::as_ Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as num_traits::cast::AsPrimitive<u32>>::as_ |
835 | | } |
836 | | }; |
837 | | ($T: tt => { $( $U: tt ),* } ) => {$( |
838 | | impl_as_primitive!(@ $T => impl $U); |
839 | | )*}; |
840 | | } |
841 | | |
842 | | impl_as_primitive!((OrderedFloat<f32>) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
843 | | impl_as_primitive!((OrderedFloat<f64>) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
844 | | |
845 | | impl_as_primitive!((NotNan<f32>) => { (NotNan<f32>), (NotNan<f64>) }); |
846 | | impl_as_primitive!((NotNan<f64>) => { (NotNan<f32>), (NotNan<f64>) }); |
847 | | |
848 | | impl_as_primitive!((u8) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
849 | | impl_as_primitive!((i8) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
850 | | impl_as_primitive!((u16) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
851 | | impl_as_primitive!((i16) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
852 | | impl_as_primitive!((u32) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
853 | | impl_as_primitive!((i32) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
854 | | impl_as_primitive!((u64) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
855 | | impl_as_primitive!((i64) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
856 | | impl_as_primitive!((usize) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
857 | | impl_as_primitive!((isize) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
858 | | impl_as_primitive!((f32) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
859 | | impl_as_primitive!((f64) => { (OrderedFloat<f32>), (OrderedFloat<f64>) }); |
860 | | |
861 | | impl_as_primitive!((u8) => { (NotNan<f32>), (NotNan<f64>) }); |
862 | | impl_as_primitive!((i8) => { (NotNan<f32>), (NotNan<f64>) }); |
863 | | impl_as_primitive!((u16) => { (NotNan<f32>), (NotNan<f64>) }); |
864 | | impl_as_primitive!((i16) => { (NotNan<f32>), (NotNan<f64>) }); |
865 | | impl_as_primitive!((u32) => { (NotNan<f32>), (NotNan<f64>) }); |
866 | | impl_as_primitive!((i32) => { (NotNan<f32>), (NotNan<f64>) }); |
867 | | impl_as_primitive!((u64) => { (NotNan<f32>), (NotNan<f64>) }); |
868 | | impl_as_primitive!((i64) => { (NotNan<f32>), (NotNan<f64>) }); |
869 | | impl_as_primitive!((usize) => { (NotNan<f32>), (NotNan<f64>) }); |
870 | | impl_as_primitive!((isize) => { (NotNan<f32>), (NotNan<f64>) }); |
871 | | |
872 | | impl_as_primitive!((OrderedFloat<f32>) => { (u8), (u16), (u32), (u64), (usize), (i8), (i16), (i32), (i64), (isize), (f32), (f64) }); |
873 | | impl_as_primitive!((OrderedFloat<f64>) => { (u8), (u16), (u32), (u64), (usize), (i8), (i16), (i32), (i64), (isize), (f32), (f64) }); |
874 | | |
875 | | impl_as_primitive!((NotNan<f32>) => { (u8), (u16), (u32), (u64), (usize), (i8), (i16), (i32), (i64), (isize), (f32), (f64) }); |
876 | | impl_as_primitive!((NotNan<f64>) => { (u8), (u16), (u32), (u64), (usize), (i8), (i16), (i32), (i64), (isize), (f32), (f64) }); |
877 | | |
878 | | impl<T: FromPrimitive> FromPrimitive for OrderedFloat<T> { |
879 | 0 | fn from_i64(n: i64) -> Option<Self> { |
880 | 0 | T::from_i64(n).map(OrderedFloat) |
881 | 0 | } |
882 | 0 | fn from_u64(n: u64) -> Option<Self> { |
883 | 0 | T::from_u64(n).map(OrderedFloat) |
884 | 0 | } |
885 | 0 | fn from_isize(n: isize) -> Option<Self> { |
886 | 0 | T::from_isize(n).map(OrderedFloat) |
887 | 0 | } |
888 | 0 | fn from_i8(n: i8) -> Option<Self> { |
889 | 0 | T::from_i8(n).map(OrderedFloat) |
890 | 0 | } |
891 | 0 | fn from_i16(n: i16) -> Option<Self> { |
892 | 0 | T::from_i16(n).map(OrderedFloat) |
893 | 0 | } |
894 | 0 | fn from_i32(n: i32) -> Option<Self> { |
895 | 0 | T::from_i32(n).map(OrderedFloat) |
896 | 0 | } |
897 | 0 | fn from_usize(n: usize) -> Option<Self> { |
898 | 0 | T::from_usize(n).map(OrderedFloat) |
899 | 0 | } |
900 | 0 | fn from_u8(n: u8) -> Option<Self> { |
901 | 0 | T::from_u8(n).map(OrderedFloat) |
902 | 0 | } |
903 | 0 | fn from_u16(n: u16) -> Option<Self> { |
904 | 0 | T::from_u16(n).map(OrderedFloat) |
905 | 0 | } |
906 | 0 | fn from_u32(n: u32) -> Option<Self> { |
907 | 0 | T::from_u32(n).map(OrderedFloat) |
908 | 0 | } |
909 | 0 | fn from_f32(n: f32) -> Option<Self> { |
910 | 0 | T::from_f32(n).map(OrderedFloat) |
911 | 0 | } |
912 | 0 | fn from_f64(n: f64) -> Option<Self> { |
913 | 0 | T::from_f64(n).map(OrderedFloat) |
914 | 0 | } |
915 | | } |
916 | | |
917 | | impl<T: ToPrimitive> ToPrimitive for OrderedFloat<T> { |
918 | 0 | fn to_i64(&self) -> Option<i64> { |
919 | 0 | self.0.to_i64() |
920 | 0 | } |
921 | 0 | fn to_u64(&self) -> Option<u64> { |
922 | 0 | self.0.to_u64() |
923 | 0 | } |
924 | 0 | fn to_isize(&self) -> Option<isize> { |
925 | 0 | self.0.to_isize() |
926 | 0 | } |
927 | 0 | fn to_i8(&self) -> Option<i8> { |
928 | 0 | self.0.to_i8() |
929 | 0 | } |
930 | 0 | fn to_i16(&self) -> Option<i16> { |
931 | 0 | self.0.to_i16() |
932 | 0 | } |
933 | 0 | fn to_i32(&self) -> Option<i32> { |
934 | 0 | self.0.to_i32() |
935 | 0 | } |
936 | 0 | fn to_usize(&self) -> Option<usize> { |
937 | 0 | self.0.to_usize() |
938 | 0 | } |
939 | 0 | fn to_u8(&self) -> Option<u8> { |
940 | 0 | self.0.to_u8() |
941 | 0 | } |
942 | 0 | fn to_u16(&self) -> Option<u16> { |
943 | 0 | self.0.to_u16() |
944 | 0 | } |
945 | 0 | fn to_u32(&self) -> Option<u32> { |
946 | 0 | self.0.to_u32() |
947 | 0 | } |
948 | 0 | fn to_f32(&self) -> Option<f32> { |
949 | 0 | self.0.to_f32() |
950 | 0 | } |
951 | 0 | fn to_f64(&self) -> Option<f64> { |
952 | 0 | self.0.to_f64() |
953 | 0 | } |
954 | | } |
955 | | |
956 | | impl<T: FloatCore> FloatCore for OrderedFloat<T> { |
957 | 0 | fn nan() -> Self { |
958 | 0 | OrderedFloat(T::nan()) |
959 | 0 | } |
960 | 0 | fn infinity() -> Self { |
961 | 0 | OrderedFloat(T::infinity()) |
962 | 0 | } |
963 | 0 | fn neg_infinity() -> Self { |
964 | 0 | OrderedFloat(T::neg_infinity()) |
965 | 0 | } |
966 | 0 | fn neg_zero() -> Self { |
967 | 0 | OrderedFloat(T::neg_zero()) |
968 | 0 | } |
969 | 0 | fn min_value() -> Self { |
970 | 0 | OrderedFloat(T::min_value()) |
971 | 0 | } |
972 | 0 | fn min_positive_value() -> Self { |
973 | 0 | OrderedFloat(T::min_positive_value()) |
974 | 0 | } |
975 | 0 | fn max_value() -> Self { |
976 | 0 | OrderedFloat(T::max_value()) |
977 | 0 | } |
978 | 0 | fn is_nan(self) -> bool { |
979 | 0 | self.0.is_nan() |
980 | 0 | } |
981 | 0 | fn is_infinite(self) -> bool { |
982 | 0 | self.0.is_infinite() |
983 | 0 | } |
984 | 0 | fn is_finite(self) -> bool { |
985 | 0 | self.0.is_finite() |
986 | 0 | } |
987 | 0 | fn is_normal(self) -> bool { |
988 | 0 | self.0.is_normal() |
989 | 0 | } |
990 | 0 | fn classify(self) -> FpCategory { |
991 | 0 | self.0.classify() |
992 | 0 | } |
993 | 0 | fn floor(self) -> Self { |
994 | 0 | OrderedFloat(self.0.floor()) |
995 | 0 | } |
996 | 0 | fn ceil(self) -> Self { |
997 | 0 | OrderedFloat(self.0.ceil()) |
998 | 0 | } |
999 | 0 | fn round(self) -> Self { |
1000 | 0 | OrderedFloat(self.0.round()) |
1001 | 0 | } |
1002 | 0 | fn trunc(self) -> Self { |
1003 | 0 | OrderedFloat(self.0.trunc()) |
1004 | 0 | } |
1005 | 0 | fn fract(self) -> Self { |
1006 | 0 | OrderedFloat(self.0.fract()) |
1007 | 0 | } |
1008 | 0 | fn abs(self) -> Self { |
1009 | 0 | OrderedFloat(self.0.abs()) |
1010 | 0 | } |
1011 | 0 | fn signum(self) -> Self { |
1012 | 0 | OrderedFloat(self.0.signum()) |
1013 | 0 | } |
1014 | 0 | fn is_sign_positive(self) -> bool { |
1015 | 0 | self.0.is_sign_positive() |
1016 | 0 | } |
1017 | 0 | fn is_sign_negative(self) -> bool { |
1018 | 0 | self.0.is_sign_negative() |
1019 | 0 | } |
1020 | 0 | fn recip(self) -> Self { |
1021 | 0 | OrderedFloat(self.0.recip()) |
1022 | 0 | } |
1023 | 0 | fn powi(self, n: i32) -> Self { |
1024 | 0 | OrderedFloat(self.0.powi(n)) |
1025 | 0 | } |
1026 | 0 | fn integer_decode(self) -> (u64, i16, i8) { |
1027 | 0 | self.0.integer_decode() |
1028 | 0 | } |
1029 | 0 | fn epsilon() -> Self { |
1030 | 0 | OrderedFloat(T::epsilon()) |
1031 | 0 | } |
1032 | 0 | fn to_degrees(self) -> Self { |
1033 | 0 | OrderedFloat(self.0.to_degrees()) |
1034 | 0 | } |
1035 | 0 | fn to_radians(self) -> Self { |
1036 | 0 | OrderedFloat(self.0.to_radians()) |
1037 | 0 | } |
1038 | | } |
1039 | | |
1040 | | #[cfg(any(feature = "std", feature = "libm"))] |
1041 | | impl<T: Float + FloatCore> Float for OrderedFloat<T> { |
1042 | 0 | fn nan() -> Self { |
1043 | 0 | OrderedFloat(<T as Float>::nan()) |
1044 | 0 | } |
1045 | 0 | fn infinity() -> Self { |
1046 | 0 | OrderedFloat(<T as Float>::infinity()) |
1047 | 0 | } |
1048 | 0 | fn neg_infinity() -> Self { |
1049 | 0 | OrderedFloat(<T as Float>::neg_infinity()) |
1050 | 0 | } |
1051 | 0 | fn neg_zero() -> Self { |
1052 | 0 | OrderedFloat(<T as Float>::neg_zero()) |
1053 | 0 | } |
1054 | 0 | fn min_value() -> Self { |
1055 | 0 | OrderedFloat(<T as Float>::min_value()) |
1056 | 0 | } |
1057 | 0 | fn min_positive_value() -> Self { |
1058 | 0 | OrderedFloat(<T as Float>::min_positive_value()) |
1059 | 0 | } |
1060 | 0 | fn max_value() -> Self { |
1061 | 0 | OrderedFloat(<T as Float>::max_value()) |
1062 | 0 | } |
1063 | 0 | fn is_nan(self) -> bool { |
1064 | 0 | Float::is_nan(self.0) |
1065 | 0 | } |
1066 | 0 | fn is_infinite(self) -> bool { |
1067 | 0 | Float::is_infinite(self.0) |
1068 | 0 | } |
1069 | 0 | fn is_finite(self) -> bool { |
1070 | 0 | Float::is_finite(self.0) |
1071 | 0 | } |
1072 | 0 | fn is_normal(self) -> bool { |
1073 | 0 | Float::is_normal(self.0) |
1074 | 0 | } |
1075 | 0 | fn classify(self) -> FpCategory { |
1076 | 0 | Float::classify(self.0) |
1077 | 0 | } |
1078 | 0 | fn floor(self) -> Self { |
1079 | 0 | OrderedFloat(Float::floor(self.0)) |
1080 | 0 | } |
1081 | 0 | fn ceil(self) -> Self { |
1082 | 0 | OrderedFloat(Float::ceil(self.0)) |
1083 | 0 | } |
1084 | 0 | fn round(self) -> Self { |
1085 | 0 | OrderedFloat(Float::round(self.0)) |
1086 | 0 | } |
1087 | 0 | fn trunc(self) -> Self { |
1088 | 0 | OrderedFloat(Float::trunc(self.0)) |
1089 | 0 | } |
1090 | 0 | fn fract(self) -> Self { |
1091 | 0 | OrderedFloat(Float::fract(self.0)) |
1092 | 0 | } |
1093 | 0 | fn abs(self) -> Self { |
1094 | 0 | OrderedFloat(Float::abs(self.0)) |
1095 | 0 | } |
1096 | 0 | fn signum(self) -> Self { |
1097 | 0 | OrderedFloat(Float::signum(self.0)) |
1098 | 0 | } |
1099 | 0 | fn is_sign_positive(self) -> bool { |
1100 | 0 | Float::is_sign_positive(self.0) |
1101 | 0 | } |
1102 | 0 | fn is_sign_negative(self) -> bool { |
1103 | 0 | Float::is_sign_negative(self.0) |
1104 | 0 | } |
1105 | 0 | fn mul_add(self, a: Self, b: Self) -> Self { |
1106 | 0 | OrderedFloat(self.0.mul_add(a.0, b.0)) |
1107 | 0 | } |
1108 | 0 | fn recip(self) -> Self { |
1109 | 0 | OrderedFloat(Float::recip(self.0)) |
1110 | 0 | } |
1111 | 0 | fn powi(self, n: i32) -> Self { |
1112 | 0 | OrderedFloat(Float::powi(self.0, n)) |
1113 | 0 | } |
1114 | 0 | fn powf(self, n: Self) -> Self { |
1115 | 0 | OrderedFloat(self.0.powf(n.0)) |
1116 | 0 | } |
1117 | 0 | fn sqrt(self) -> Self { |
1118 | 0 | OrderedFloat(self.0.sqrt()) |
1119 | 0 | } |
1120 | 0 | fn exp(self) -> Self { |
1121 | 0 | OrderedFloat(self.0.exp()) |
1122 | 0 | } |
1123 | 0 | fn exp2(self) -> Self { |
1124 | 0 | OrderedFloat(self.0.exp2()) |
1125 | 0 | } |
1126 | 0 | fn ln(self) -> Self { |
1127 | 0 | OrderedFloat(self.0.ln()) |
1128 | 0 | } |
1129 | 0 | fn log(self, base: Self) -> Self { |
1130 | 0 | OrderedFloat(self.0.log(base.0)) |
1131 | 0 | } |
1132 | 0 | fn log2(self) -> Self { |
1133 | 0 | OrderedFloat(self.0.log2()) |
1134 | 0 | } |
1135 | 0 | fn log10(self) -> Self { |
1136 | 0 | OrderedFloat(self.0.log10()) |
1137 | 0 | } |
1138 | 0 | fn max(self, other: Self) -> Self { |
1139 | 0 | OrderedFloat(Float::max(self.0, other.0)) |
1140 | 0 | } |
1141 | 0 | fn min(self, other: Self) -> Self { |
1142 | 0 | OrderedFloat(Float::min(self.0, other.0)) |
1143 | 0 | } |
1144 | 0 | fn abs_sub(self, other: Self) -> Self { |
1145 | 0 | OrderedFloat(self.0.abs_sub(other.0)) |
1146 | 0 | } |
1147 | 0 | fn cbrt(self) -> Self { |
1148 | 0 | OrderedFloat(self.0.cbrt()) |
1149 | 0 | } |
1150 | 0 | fn hypot(self, other: Self) -> Self { |
1151 | 0 | OrderedFloat(self.0.hypot(other.0)) |
1152 | 0 | } |
1153 | 0 | fn sin(self) -> Self { |
1154 | 0 | OrderedFloat(self.0.sin()) |
1155 | 0 | } |
1156 | 0 | fn cos(self) -> Self { |
1157 | 0 | OrderedFloat(self.0.cos()) |
1158 | 0 | } |
1159 | 0 | fn tan(self) -> Self { |
1160 | 0 | OrderedFloat(self.0.tan()) |
1161 | 0 | } |
1162 | 0 | fn asin(self) -> Self { |
1163 | 0 | OrderedFloat(self.0.asin()) |
1164 | 0 | } |
1165 | 0 | fn acos(self) -> Self { |
1166 | 0 | OrderedFloat(self.0.acos()) |
1167 | 0 | } |
1168 | 0 | fn atan(self) -> Self { |
1169 | 0 | OrderedFloat(self.0.atan()) |
1170 | 0 | } |
1171 | 0 | fn atan2(self, other: Self) -> Self { |
1172 | 0 | OrderedFloat(self.0.atan2(other.0)) |
1173 | 0 | } |
1174 | 0 | fn sin_cos(self) -> (Self, Self) { |
1175 | 0 | let (a, b) = self.0.sin_cos(); |
1176 | 0 | (OrderedFloat(a), OrderedFloat(b)) |
1177 | 0 | } |
1178 | 0 | fn exp_m1(self) -> Self { |
1179 | 0 | OrderedFloat(self.0.exp_m1()) |
1180 | 0 | } |
1181 | 0 | fn ln_1p(self) -> Self { |
1182 | 0 | OrderedFloat(self.0.ln_1p()) |
1183 | 0 | } |
1184 | 0 | fn sinh(self) -> Self { |
1185 | 0 | OrderedFloat(self.0.sinh()) |
1186 | 0 | } |
1187 | 0 | fn cosh(self) -> Self { |
1188 | 0 | OrderedFloat(self.0.cosh()) |
1189 | 0 | } |
1190 | 0 | fn tanh(self) -> Self { |
1191 | 0 | OrderedFloat(self.0.tanh()) |
1192 | 0 | } |
1193 | 0 | fn asinh(self) -> Self { |
1194 | 0 | OrderedFloat(self.0.asinh()) |
1195 | 0 | } |
1196 | 0 | fn acosh(self) -> Self { |
1197 | 0 | OrderedFloat(self.0.acosh()) |
1198 | 0 | } |
1199 | 0 | fn atanh(self) -> Self { |
1200 | 0 | OrderedFloat(self.0.atanh()) |
1201 | 0 | } |
1202 | 0 | fn integer_decode(self) -> (u64, i16, i8) { |
1203 | 0 | Float::integer_decode(self.0) |
1204 | 0 | } |
1205 | 0 | fn epsilon() -> Self { |
1206 | 0 | OrderedFloat(<T as Float>::epsilon()) |
1207 | 0 | } |
1208 | 0 | fn to_degrees(self) -> Self { |
1209 | 0 | OrderedFloat(Float::to_degrees(self.0)) |
1210 | 0 | } |
1211 | 0 | fn to_radians(self) -> Self { |
1212 | 0 | OrderedFloat(Float::to_radians(self.0)) |
1213 | 0 | } |
1214 | | } |
1215 | | |
1216 | | impl<T: FloatCore + Num> Num for OrderedFloat<T> { |
1217 | | type FromStrRadixErr = T::FromStrRadixErr; |
1218 | 0 | fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> { |
1219 | 0 | T::from_str_radix(str, radix).map(OrderedFloat) |
1220 | 0 | } |
1221 | | } |
1222 | | |
1223 | | /// A wrapper around floats providing an implementation of `Eq`, `Ord` and `Hash`. |
1224 | | /// |
1225 | | /// A NaN value cannot be stored in this type. |
1226 | | /// |
1227 | | /// ``` |
1228 | | /// use ordered_float::NotNan; |
1229 | | /// |
1230 | | /// let mut v = [ |
1231 | | /// NotNan::new(2.0).unwrap(), |
1232 | | /// NotNan::new(1.0).unwrap(), |
1233 | | /// ]; |
1234 | | /// v.sort(); |
1235 | | /// assert_eq!(v, [1.0, 2.0]); |
1236 | | /// ``` |
1237 | | /// |
1238 | | /// Because `NotNan` implements `Ord` and `Eq`, it can be used as a key in a `HashSet`, |
1239 | | /// `HashMap`, `BTreeMap`, or `BTreeSet` (unlike the primitive `f32` or `f64` types): |
1240 | | /// |
1241 | | /// ``` |
1242 | | /// # use ordered_float::NotNan; |
1243 | | /// # use std::collections::HashSet; |
1244 | | /// let mut s: HashSet<NotNan<f32>> = HashSet::new(); |
1245 | | /// let key = NotNan::new(1.0).unwrap(); |
1246 | | /// s.insert(key); |
1247 | | /// assert!(s.contains(&key)); |
1248 | | /// ``` |
1249 | | /// |
1250 | | /// `-0.0` and `+0.0` are still considered equal. This different sign may show up in printing, |
1251 | | /// or when dividing by zero (the sign of the zero becomes the sign of the resulting infinity). |
1252 | | /// Therefore, `NotNan` may be unsuitable for use as a key in interning and memoization |
1253 | | /// applications which require equal results from equal inputs, unless signed zeros make no |
1254 | | /// difference or are canonicalized before insertion. |
1255 | | /// |
1256 | | /// Arithmetic on NotNan values will panic if it produces a NaN value: |
1257 | | /// |
1258 | | /// ```should_panic |
1259 | | /// # use ordered_float::NotNan; |
1260 | | /// let a = NotNan::new(std::f32::INFINITY).unwrap(); |
1261 | | /// let b = NotNan::new(std::f32::NEG_INFINITY).unwrap(); |
1262 | | /// |
1263 | | /// // This will panic: |
1264 | | /// let c = a + b; |
1265 | | /// ``` |
1266 | | /// |
1267 | | /// # Representation |
1268 | | /// |
1269 | | /// `NotNan` has `#[repr(transparent)]`, so it is sound to use |
1270 | | /// [transmute](core::mem::transmute) or pointer casts to convert between any type `T` and |
1271 | | /// `NotNan<T>`, as long as this does not create a NaN value. |
1272 | | /// However, consider using [`bytemuck`] as a safe alternative if possible. |
1273 | | /// |
1274 | | #[cfg_attr( |
1275 | | not(feature = "bytemuck"), |
1276 | | doc = "[`bytemuck`]: https://docs.rs/bytemuck/1/" |
1277 | | )] |
1278 | | #[derive(PartialOrd, PartialEq, Default, Clone, Copy)] |
1279 | | #[repr(transparent)] |
1280 | | pub struct NotNan<T>(T); |
1281 | | |
1282 | | impl<T: FloatCore> NotNan<T> { |
1283 | | /// Create a `NotNan` value. |
1284 | | /// |
1285 | | /// Returns `Err` if `val` is NaN |
1286 | 0 | pub fn new(val: T) -> Result<Self, FloatIsNan> { |
1287 | 0 | match val { |
1288 | 0 | ref val if val.is_nan() => Err(FloatIsNan), |
1289 | 0 | val => Ok(NotNan(val)), |
1290 | | } |
1291 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<f64>>::new Unexecuted instantiation: <ordered_float::NotNan<f32>>::new |
1292 | | } |
1293 | | |
1294 | | impl<T> NotNan<T> { |
1295 | | /// Get the value out. |
1296 | | #[inline] |
1297 | 0 | pub fn into_inner(self) -> T { |
1298 | 0 | self.0 |
1299 | 0 | } |
1300 | | |
1301 | | /// Create a `NotNan` value from a value that is guaranteed to not be NaN |
1302 | | /// |
1303 | | /// # Safety |
1304 | | /// |
1305 | | /// Behaviour is undefined if `val` is NaN |
1306 | | #[inline] |
1307 | 0 | pub const unsafe fn new_unchecked(val: T) -> Self { |
1308 | 0 | NotNan(val) |
1309 | 0 | } |
1310 | | |
1311 | | /// Create a `NotNan` value from a value that is guaranteed to not be NaN |
1312 | | /// |
1313 | | /// # Safety |
1314 | | /// |
1315 | | /// Behaviour is undefined if `val` is NaN |
1316 | | #[deprecated( |
1317 | | since = "2.5.0", |
1318 | | note = "Please use the new_unchecked function instead." |
1319 | | )] |
1320 | | #[inline] |
1321 | 0 | pub const unsafe fn unchecked_new(val: T) -> Self { |
1322 | 0 | Self::new_unchecked(val) |
1323 | 0 | } |
1324 | | } |
1325 | | |
1326 | | impl<T: FloatCore> AsRef<T> for NotNan<T> { |
1327 | | #[inline] |
1328 | 0 | fn as_ref(&self) -> &T { |
1329 | 0 | &self.0 |
1330 | 0 | } |
1331 | | } |
1332 | | |
1333 | | impl Borrow<f32> for NotNan<f32> { |
1334 | | #[inline] |
1335 | 0 | fn borrow(&self) -> &f32 { |
1336 | 0 | &self.0 |
1337 | 0 | } |
1338 | | } |
1339 | | |
1340 | | impl Borrow<f64> for NotNan<f64> { |
1341 | | #[inline] |
1342 | 0 | fn borrow(&self) -> &f64 { |
1343 | 0 | &self.0 |
1344 | 0 | } |
1345 | | } |
1346 | | |
1347 | | #[allow(clippy::derive_ord_xor_partial_ord)] |
1348 | | impl<T: FloatCore> Ord for NotNan<T> { |
1349 | 0 | fn cmp(&self, other: &NotNan<T>) -> Ordering { |
1350 | | // Can't use unreachable_unchecked because unsafe code can't depend on FloatCore impl. |
1351 | | // https://github.com/reem/rust-ordered-float/issues/150 |
1352 | 0 | self.partial_cmp(other) |
1353 | 0 | .expect("partial_cmp failed for non-NaN value") |
1354 | 0 | } |
1355 | | } |
1356 | | |
1357 | | impl<T: FloatCore> Hash for NotNan<T> { |
1358 | | #[inline] |
1359 | 0 | fn hash<H: Hasher>(&self, state: &mut H) { |
1360 | 0 | let bits = raw_double_bits(&canonicalize_signed_zero(self.0)); |
1361 | 0 | bits.hash(state) |
1362 | 0 | } |
1363 | | } |
1364 | | |
1365 | | impl<T: fmt::Debug> fmt::Debug for NotNan<T> { |
1366 | | #[inline] |
1367 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1368 | 0 | self.0.fmt(f) |
1369 | 0 | } |
1370 | | } |
1371 | | |
1372 | | impl<T: FloatCore + fmt::Display> fmt::Display for NotNan<T> { |
1373 | | #[inline] |
1374 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1375 | 0 | self.0.fmt(f) |
1376 | 0 | } |
1377 | | } |
1378 | | |
1379 | | impl NotNan<f64> { |
1380 | | /// Converts this [`NotNan`]`<`[`f64`]`>` to a [`NotNan`]`<`[`f32`]`>` while giving up on |
1381 | | /// precision, [using `roundTiesToEven` as rounding mode, yielding `Infinity` on |
1382 | | /// overflow](https://doc.rust-lang.org/reference/expressions/operator-expr.html#semantics). |
1383 | | /// |
1384 | | /// Note: For the reverse conversion (from `NotNan<f32>` to `NotNan<f64>`), you can use |
1385 | | /// `.into()`. |
1386 | 0 | pub fn as_f32(self) -> NotNan<f32> { |
1387 | | // This is not destroying invariants, as it is a pure rounding operation. The only two special |
1388 | | // cases are where f32 would be overflowing, then the operation yields Infinity, or where |
1389 | | // the input is already NaN, in which case the invariant is already broken elsewhere. |
1390 | 0 | NotNan(self.0 as f32) |
1391 | 0 | } |
1392 | | } |
1393 | | |
1394 | | impl From<NotNan<f32>> for f32 { |
1395 | | #[inline] |
1396 | 0 | fn from(value: NotNan<f32>) -> Self { |
1397 | 0 | value.0 |
1398 | 0 | } |
1399 | | } |
1400 | | |
1401 | | impl From<NotNan<f64>> for f64 { |
1402 | | #[inline] |
1403 | 0 | fn from(value: NotNan<f64>) -> Self { |
1404 | 0 | value.0 |
1405 | 0 | } |
1406 | | } |
1407 | | |
1408 | | impl TryFrom<f32> for NotNan<f32> { |
1409 | | type Error = FloatIsNan; |
1410 | | #[inline] |
1411 | 0 | fn try_from(v: f32) -> Result<Self, Self::Error> { |
1412 | 0 | NotNan::new(v) |
1413 | 0 | } |
1414 | | } |
1415 | | |
1416 | | impl TryFrom<f64> for NotNan<f64> { |
1417 | | type Error = FloatIsNan; |
1418 | | #[inline] |
1419 | 0 | fn try_from(v: f64) -> Result<Self, Self::Error> { |
1420 | 0 | NotNan::new(v) |
1421 | 0 | } |
1422 | | } |
1423 | | |
1424 | | macro_rules! impl_from_int_primitive { |
1425 | | ($primitive:ty, $inner:ty) => { |
1426 | | impl From<$primitive> for NotNan<$inner> { |
1427 | 0 | fn from(source: $primitive) -> Self { |
1428 | | // the primitives with which this macro will be called cannot hold a value that |
1429 | | // f64::from would convert to NaN, so this does not hurt invariants |
1430 | 0 | NotNan(<$inner as From<$primitive>>::from(source)) |
1431 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<f64> as core::convert::From<i8>>::from Unexecuted instantiation: <ordered_float::NotNan<f64> as core::convert::From<i16>>::from Unexecuted instantiation: <ordered_float::NotNan<f64> as core::convert::From<i32>>::from Unexecuted instantiation: <ordered_float::NotNan<f64> as core::convert::From<u8>>::from Unexecuted instantiation: <ordered_float::NotNan<f64> as core::convert::From<u16>>::from Unexecuted instantiation: <ordered_float::NotNan<f64> as core::convert::From<u32>>::from Unexecuted instantiation: <ordered_float::NotNan<f32> as core::convert::From<i8>>::from Unexecuted instantiation: <ordered_float::NotNan<f32> as core::convert::From<i16>>::from Unexecuted instantiation: <ordered_float::NotNan<f32> as core::convert::From<u8>>::from Unexecuted instantiation: <ordered_float::NotNan<f32> as core::convert::From<u16>>::from |
1432 | | } |
1433 | | }; |
1434 | | } |
1435 | | |
1436 | | impl_from_int_primitive!(i8, f64); |
1437 | | impl_from_int_primitive!(i16, f64); |
1438 | | impl_from_int_primitive!(i32, f64); |
1439 | | impl_from_int_primitive!(u8, f64); |
1440 | | impl_from_int_primitive!(u16, f64); |
1441 | | impl_from_int_primitive!(u32, f64); |
1442 | | |
1443 | | impl_from_int_primitive!(i8, f32); |
1444 | | impl_from_int_primitive!(i16, f32); |
1445 | | impl_from_int_primitive!(u8, f32); |
1446 | | impl_from_int_primitive!(u16, f32); |
1447 | | |
1448 | | impl From<NotNan<f32>> for NotNan<f64> { |
1449 | | #[inline] |
1450 | 0 | fn from(v: NotNan<f32>) -> NotNan<f64> { |
1451 | 0 | unsafe { NotNan::new_unchecked(v.0 as f64) } |
1452 | 0 | } |
1453 | | } |
1454 | | |
1455 | | impl<T: FloatCore> Deref for NotNan<T> { |
1456 | | type Target = T; |
1457 | | |
1458 | | #[inline] |
1459 | 0 | fn deref(&self) -> &Self::Target { |
1460 | 0 | &self.0 |
1461 | 0 | } |
1462 | | } |
1463 | | |
1464 | | impl<T: FloatCore + PartialEq> Eq for NotNan<T> {} |
1465 | | |
1466 | | impl<T: FloatCore> PartialEq<T> for NotNan<T> { |
1467 | | #[inline] |
1468 | 0 | fn eq(&self, other: &T) -> bool { |
1469 | 0 | self.0 == *other |
1470 | 0 | } |
1471 | | } |
1472 | | |
1473 | | /// Adds a float directly. |
1474 | | /// |
1475 | | /// Panics if the provided value is NaN or the computation results in NaN |
1476 | | impl<T: FloatCore> Add<T> for NotNan<T> { |
1477 | | type Output = Self; |
1478 | | |
1479 | | #[inline] |
1480 | 0 | fn add(self, other: T) -> Self { |
1481 | 0 | NotNan::new(self.0 + other).expect("Addition resulted in NaN") |
1482 | 0 | } |
1483 | | } |
1484 | | |
1485 | | /// Adds a float directly. |
1486 | | /// |
1487 | | /// Panics if the provided value is NaN. |
1488 | | impl<T: FloatCore + Sum> Sum for NotNan<T> { |
1489 | 0 | fn sum<I: Iterator<Item = NotNan<T>>>(iter: I) -> Self { |
1490 | 0 | NotNan::new(iter.map(|v| v.0).sum()).expect("Sum resulted in NaN") |
1491 | 0 | } |
1492 | | } |
1493 | | |
1494 | | impl<'a, T: FloatCore + Sum + 'a> Sum<&'a NotNan<T>> for NotNan<T> { |
1495 | | #[inline] |
1496 | 0 | fn sum<I: Iterator<Item = &'a NotNan<T>>>(iter: I) -> Self { |
1497 | 0 | iter.cloned().sum() |
1498 | 0 | } |
1499 | | } |
1500 | | |
1501 | | /// Subtracts a float directly. |
1502 | | /// |
1503 | | /// Panics if the provided value is NaN or the computation results in NaN |
1504 | | impl<T: FloatCore> Sub<T> for NotNan<T> { |
1505 | | type Output = Self; |
1506 | | |
1507 | | #[inline] |
1508 | 0 | fn sub(self, other: T) -> Self { |
1509 | 0 | NotNan::new(self.0 - other).expect("Subtraction resulted in NaN") |
1510 | 0 | } |
1511 | | } |
1512 | | |
1513 | | /// Multiplies a float directly. |
1514 | | /// |
1515 | | /// Panics if the provided value is NaN or the computation results in NaN |
1516 | | impl<T: FloatCore> Mul<T> for NotNan<T> { |
1517 | | type Output = Self; |
1518 | | |
1519 | | #[inline] |
1520 | 0 | fn mul(self, other: T) -> Self { |
1521 | 0 | NotNan::new(self.0 * other).expect("Multiplication resulted in NaN") |
1522 | 0 | } |
1523 | | } |
1524 | | |
1525 | | impl<T: FloatCore + Product> Product for NotNan<T> { |
1526 | 0 | fn product<I: Iterator<Item = NotNan<T>>>(iter: I) -> Self { |
1527 | 0 | NotNan::new(iter.map(|v| v.0).product()).expect("Product resulted in NaN") |
1528 | 0 | } |
1529 | | } |
1530 | | |
1531 | | impl<'a, T: FloatCore + Product + 'a> Product<&'a NotNan<T>> for NotNan<T> { |
1532 | | #[inline] |
1533 | 0 | fn product<I: Iterator<Item = &'a NotNan<T>>>(iter: I) -> Self { |
1534 | 0 | iter.cloned().product() |
1535 | 0 | } |
1536 | | } |
1537 | | |
1538 | | /// Divides a float directly. |
1539 | | /// |
1540 | | /// Panics if the provided value is NaN or the computation results in NaN |
1541 | | impl<T: FloatCore> Div<T> for NotNan<T> { |
1542 | | type Output = Self; |
1543 | | |
1544 | | #[inline] |
1545 | 0 | fn div(self, other: T) -> Self { |
1546 | 0 | NotNan::new(self.0 / other).expect("Division resulted in NaN") |
1547 | 0 | } |
1548 | | } |
1549 | | |
1550 | | /// Calculates `%` with a float directly. |
1551 | | /// |
1552 | | /// Panics if the provided value is NaN or the computation results in NaN |
1553 | | impl<T: FloatCore> Rem<T> for NotNan<T> { |
1554 | | type Output = Self; |
1555 | | |
1556 | | #[inline] |
1557 | 0 | fn rem(self, other: T) -> Self { |
1558 | 0 | NotNan::new(self.0 % other).expect("Rem resulted in NaN") |
1559 | 0 | } |
1560 | | } |
1561 | | |
1562 | | macro_rules! impl_not_nan_binop { |
1563 | | ($imp:ident, $method:ident, $assign_imp:ident, $assign_method:ident) => { |
1564 | | impl<T: FloatCore> $imp for NotNan<T> { |
1565 | | type Output = Self; |
1566 | | |
1567 | | #[inline] |
1568 | 0 | fn $method(self, other: Self) -> Self { |
1569 | 0 | self.$method(other.0) |
1570 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Div>::div Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Add>::add Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Rem>::rem |
1571 | | } |
1572 | | |
1573 | | impl<T: FloatCore> $imp<&T> for NotNan<T> { |
1574 | | type Output = NotNan<T>; |
1575 | | |
1576 | | #[inline] |
1577 | 0 | fn $method(self, other: &T) -> Self::Output { |
1578 | 0 | self.$method(*other) |
1579 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Mul<&_>>::mul Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Div<&_>>::div Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Add<&_>>::add Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Sub<&_>>::sub Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Rem<&_>>::rem |
1580 | | } |
1581 | | |
1582 | | impl<T: FloatCore> $imp<&Self> for NotNan<T> { |
1583 | | type Output = NotNan<T>; |
1584 | | |
1585 | | #[inline] |
1586 | 0 | fn $method(self, other: &Self) -> Self::Output { |
1587 | 0 | self.$method(other.0) |
1588 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Sub<&ordered_float::NotNan<_>>>::sub Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Mul<&ordered_float::NotNan<_>>>::mul Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Div<&ordered_float::NotNan<_>>>::div Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Add<&ordered_float::NotNan<_>>>::add Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::Rem<&ordered_float::NotNan<_>>>::rem |
1589 | | } |
1590 | | |
1591 | | impl<T: FloatCore> $imp for &NotNan<T> { |
1592 | | type Output = NotNan<T>; |
1593 | | |
1594 | | #[inline] |
1595 | 0 | fn $method(self, other: Self) -> Self::Output { |
1596 | 0 | (*self).$method(other.0) |
1597 | 0 | } Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Sub>::sub Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Mul>::mul Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Div>::div Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Add>::add Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Rem>::rem |
1598 | | } |
1599 | | |
1600 | | impl<T: FloatCore> $imp<NotNan<T>> for &NotNan<T> { |
1601 | | type Output = NotNan<T>; |
1602 | | |
1603 | | #[inline] |
1604 | 0 | fn $method(self, other: NotNan<T>) -> Self::Output { |
1605 | 0 | (*self).$method(other.0) |
1606 | 0 | } Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Sub<ordered_float::NotNan<_>>>::sub Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Mul<ordered_float::NotNan<_>>>::mul Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Div<ordered_float::NotNan<_>>>::div Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Add<ordered_float::NotNan<_>>>::add Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Rem<ordered_float::NotNan<_>>>::rem |
1607 | | } |
1608 | | |
1609 | | impl<T: FloatCore> $imp<T> for &NotNan<T> { |
1610 | | type Output = NotNan<T>; |
1611 | | |
1612 | | #[inline] |
1613 | 0 | fn $method(self, other: T) -> Self::Output { |
1614 | 0 | (*self).$method(other) |
1615 | 0 | } Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Sub<_>>::sub Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Mul<_>>::mul Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Div<_>>::div Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Add<_>>::add Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Rem<_>>::rem |
1616 | | } |
1617 | | |
1618 | | impl<T: FloatCore> $imp<&T> for &NotNan<T> { |
1619 | | type Output = NotNan<T>; |
1620 | | |
1621 | | #[inline] |
1622 | 0 | fn $method(self, other: &T) -> Self::Output { |
1623 | 0 | (*self).$method(*other) |
1624 | 0 | } Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Sub<&_>>::sub Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Mul<&_>>::mul Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Add<&_>>::add Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Div<&_>>::div Unexecuted instantiation: <&ordered_float::NotNan<_> as core::ops::arith::Rem<&_>>::rem |
1625 | | } |
1626 | | |
1627 | | impl<T: FloatCore + $assign_imp> $assign_imp<T> for NotNan<T> { |
1628 | | #[inline] |
1629 | 0 | fn $assign_method(&mut self, other: T) { |
1630 | 0 | *self = (*self).$method(other); |
1631 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::SubAssign<_>>::sub_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::MulAssign<_>>::mul_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::AddAssign<_>>::add_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::DivAssign<_>>::div_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::RemAssign<_>>::rem_assign |
1632 | | } |
1633 | | |
1634 | | impl<T: FloatCore + $assign_imp> $assign_imp<&T> for NotNan<T> { |
1635 | | #[inline] |
1636 | 0 | fn $assign_method(&mut self, other: &T) { |
1637 | 0 | *self = (*self).$method(*other); |
1638 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::SubAssign<&_>>::sub_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::MulAssign<&_>>::mul_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::AddAssign<&_>>::add_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::DivAssign<&_>>::div_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::RemAssign<&_>>::rem_assign |
1639 | | } |
1640 | | |
1641 | | impl<T: FloatCore + $assign_imp> $assign_imp for NotNan<T> { |
1642 | | #[inline] |
1643 | 0 | fn $assign_method(&mut self, other: Self) { |
1644 | 0 | (*self).$assign_method(other.0); |
1645 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::SubAssign>::sub_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::MulAssign>::mul_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::AddAssign>::add_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::DivAssign>::div_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::RemAssign>::rem_assign |
1646 | | } |
1647 | | |
1648 | | impl<T: FloatCore + $assign_imp> $assign_imp<&Self> for NotNan<T> { |
1649 | | #[inline] |
1650 | 0 | fn $assign_method(&mut self, other: &Self) { |
1651 | 0 | (*self).$assign_method(other.0); |
1652 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::SubAssign<&ordered_float::NotNan<_>>>::sub_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::MulAssign<&ordered_float::NotNan<_>>>::mul_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::AddAssign<&ordered_float::NotNan<_>>>::add_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::DivAssign<&ordered_float::NotNan<_>>>::div_assign Unexecuted instantiation: <ordered_float::NotNan<_> as core::ops::arith::RemAssign<&ordered_float::NotNan<_>>>::rem_assign |
1653 | | } |
1654 | | }; |
1655 | | } |
1656 | | |
1657 | | impl_not_nan_binop! {Add, add, AddAssign, add_assign} |
1658 | | impl_not_nan_binop! {Sub, sub, SubAssign, sub_assign} |
1659 | | impl_not_nan_binop! {Mul, mul, MulAssign, mul_assign} |
1660 | | impl_not_nan_binop! {Div, div, DivAssign, div_assign} |
1661 | | impl_not_nan_binop! {Rem, rem, RemAssign, rem_assign} |
1662 | | |
1663 | | // Will panic if NaN value is return from the operation |
1664 | | macro_rules! impl_not_nan_pow { |
1665 | | ($inner:ty, $rhs:ty) => { |
1666 | | #[cfg(any(feature = "std", feature = "libm"))] |
1667 | | impl Pow<$rhs> for NotNan<$inner> { |
1668 | | type Output = NotNan<$inner>; |
1669 | | #[inline] |
1670 | 0 | fn pow(self, rhs: $rhs) -> NotNan<$inner> { |
1671 | 0 | NotNan::new(<$inner>::pow(self.0, rhs)).expect("Pow resulted in NaN") |
1672 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<i8>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<i16>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<u8>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<u16>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<i32>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<f32>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<f32>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<i8>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<i16>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<u8>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<u16>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<i32>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<f64>>::pow |
1673 | | } |
1674 | | |
1675 | | #[cfg(any(feature = "std", feature = "libm"))] |
1676 | | impl<'a> Pow<&'a $rhs> for NotNan<$inner> { |
1677 | | type Output = NotNan<$inner>; |
1678 | | #[inline] |
1679 | 0 | fn pow(self, rhs: &'a $rhs) -> NotNan<$inner> { |
1680 | 0 | NotNan::new(<$inner>::pow(self.0, *rhs)).expect("Pow resulted in NaN") |
1681 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<&i8>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<&i16>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<&u8>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<&u16>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<&i32>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<&f32>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<&f32>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<&i8>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<&i16>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<&u8>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<&u16>>::pow Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<&i32>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<&f64>>::pow |
1682 | | } |
1683 | | |
1684 | | #[cfg(any(feature = "std", feature = "libm"))] |
1685 | | impl<'a> Pow<$rhs> for &'a NotNan<$inner> { |
1686 | | type Output = NotNan<$inner>; |
1687 | | #[inline] |
1688 | 0 | fn pow(self, rhs: $rhs) -> NotNan<$inner> { |
1689 | 0 | NotNan::new(<$inner>::pow(self.0, rhs)).expect("Pow resulted in NaN") |
1690 | 0 | } Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<i8>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<i16>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<u8>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<u16>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<i32>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<f32>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<i8>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<i16>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<u8>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<u16>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<i32>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<f32>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<f64>>::pow |
1691 | | } |
1692 | | |
1693 | | #[cfg(any(feature = "std", feature = "libm"))] |
1694 | | impl<'a, 'b> Pow<&'a $rhs> for &'b NotNan<$inner> { |
1695 | | type Output = NotNan<$inner>; |
1696 | | #[inline] |
1697 | 0 | fn pow(self, rhs: &'a $rhs) -> NotNan<$inner> { |
1698 | 0 | NotNan::new(<$inner>::pow(self.0, *rhs)).expect("Pow resulted in NaN") |
1699 | 0 | } Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<&i8>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<&i16>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<&u8>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<&u16>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<&i32>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<&f32>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<&i8>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<&i16>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<&u8>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<&u16>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<&i32>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<&f32>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<&f64>>::pow |
1700 | | } |
1701 | | }; |
1702 | | } |
1703 | | |
1704 | | impl_not_nan_pow! {f32, i8} |
1705 | | impl_not_nan_pow! {f32, i16} |
1706 | | impl_not_nan_pow! {f32, u8} |
1707 | | impl_not_nan_pow! {f32, u16} |
1708 | | impl_not_nan_pow! {f32, i32} |
1709 | | impl_not_nan_pow! {f64, i8} |
1710 | | impl_not_nan_pow! {f64, i16} |
1711 | | impl_not_nan_pow! {f64, u8} |
1712 | | impl_not_nan_pow! {f64, u16} |
1713 | | impl_not_nan_pow! {f64, i32} |
1714 | | impl_not_nan_pow! {f32, f32} |
1715 | | impl_not_nan_pow! {f64, f32} |
1716 | | impl_not_nan_pow! {f64, f64} |
1717 | | |
1718 | | // This also should panic on NaN |
1719 | | macro_rules! impl_not_nan_self_pow { |
1720 | | ($base:ty, $exp:ty) => { |
1721 | | #[cfg(any(feature = "std", feature = "libm"))] |
1722 | | impl Pow<NotNan<$exp>> for NotNan<$base> { |
1723 | | type Output = NotNan<$base>; |
1724 | | #[inline] |
1725 | 0 | fn pow(self, rhs: NotNan<$exp>) -> NotNan<$base> { |
1726 | 0 | NotNan::new(self.0.pow(rhs.0)).expect("Pow resulted in NaN") |
1727 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<ordered_float::NotNan<f32>>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<ordered_float::NotNan<f32>>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<ordered_float::NotNan<f64>>>::pow |
1728 | | } |
1729 | | |
1730 | | #[cfg(any(feature = "std", feature = "libm"))] |
1731 | | impl<'a> Pow<&'a NotNan<$exp>> for NotNan<$base> { |
1732 | | type Output = NotNan<$base>; |
1733 | | #[inline] |
1734 | 0 | fn pow(self, rhs: &'a NotNan<$exp>) -> NotNan<$base> { |
1735 | 0 | NotNan::new(self.0.pow(rhs.0)).expect("Pow resulted in NaN") |
1736 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<f32> as num_traits::pow::Pow<&ordered_float::NotNan<f32>>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<&ordered_float::NotNan<f32>>>::pow Unexecuted instantiation: <ordered_float::NotNan<f64> as num_traits::pow::Pow<&ordered_float::NotNan<f64>>>::pow |
1737 | | } |
1738 | | |
1739 | | #[cfg(any(feature = "std", feature = "libm"))] |
1740 | | impl<'a> Pow<NotNan<$exp>> for &'a NotNan<$base> { |
1741 | | type Output = NotNan<$base>; |
1742 | | #[inline] |
1743 | 0 | fn pow(self, rhs: NotNan<$exp>) -> NotNan<$base> { |
1744 | 0 | NotNan::new(self.0.pow(rhs.0)).expect("Pow resulted in NaN") |
1745 | 0 | } Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<ordered_float::NotNan<f32>>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<ordered_float::NotNan<f32>>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<ordered_float::NotNan<f64>>>::pow |
1746 | | } |
1747 | | |
1748 | | #[cfg(any(feature = "std", feature = "libm"))] |
1749 | | impl<'a, 'b> Pow<&'a NotNan<$exp>> for &'b NotNan<$base> { |
1750 | | type Output = NotNan<$base>; |
1751 | | #[inline] |
1752 | 0 | fn pow(self, rhs: &'a NotNan<$exp>) -> NotNan<$base> { |
1753 | 0 | NotNan::new(self.0.pow(rhs.0)).expect("Pow resulted in NaN") |
1754 | 0 | } Unexecuted instantiation: <&ordered_float::NotNan<f32> as num_traits::pow::Pow<&ordered_float::NotNan<f32>>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<&ordered_float::NotNan<f32>>>::pow Unexecuted instantiation: <&ordered_float::NotNan<f64> as num_traits::pow::Pow<&ordered_float::NotNan<f64>>>::pow |
1755 | | } |
1756 | | }; |
1757 | | } |
1758 | | |
1759 | | impl_not_nan_self_pow! {f32, f32} |
1760 | | impl_not_nan_self_pow! {f64, f32} |
1761 | | impl_not_nan_self_pow! {f64, f64} |
1762 | | |
1763 | | impl<T: FloatCore> Neg for NotNan<T> { |
1764 | | type Output = Self; |
1765 | | |
1766 | | #[inline] |
1767 | 0 | fn neg(self) -> Self { |
1768 | 0 | NotNan(-self.0) |
1769 | 0 | } |
1770 | | } |
1771 | | |
1772 | | impl<T: FloatCore> Neg for &NotNan<T> { |
1773 | | type Output = NotNan<T>; |
1774 | | |
1775 | | #[inline] |
1776 | 0 | fn neg(self) -> Self::Output { |
1777 | 0 | NotNan(-self.0) |
1778 | 0 | } |
1779 | | } |
1780 | | |
1781 | | /// An error indicating an attempt to construct NotNan from a NaN |
1782 | | #[derive(Copy, Clone, PartialEq, Eq, Debug)] |
1783 | | pub struct FloatIsNan; |
1784 | | |
1785 | | #[cfg(feature = "std")] |
1786 | | impl Error for FloatIsNan { |
1787 | 0 | fn description(&self) -> &str { |
1788 | 0 | "NotNan constructed with NaN" |
1789 | 0 | } |
1790 | | } |
1791 | | |
1792 | | impl fmt::Display for FloatIsNan { |
1793 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1794 | 0 | write!(f, "NotNan constructed with NaN") |
1795 | 0 | } |
1796 | | } |
1797 | | |
1798 | | #[cfg(feature = "std")] |
1799 | | impl From<FloatIsNan> for std::io::Error { |
1800 | | #[inline] |
1801 | 0 | fn from(e: FloatIsNan) -> std::io::Error { |
1802 | 0 | std::io::Error::new(std::io::ErrorKind::InvalidInput, e) |
1803 | 0 | } |
1804 | | } |
1805 | | |
1806 | | #[inline] |
1807 | | /// Used for hashing. Input must not be zero or NaN. |
1808 | 0 | fn raw_double_bits<F: FloatCore>(f: &F) -> u64 { |
1809 | 0 | let (man, exp, sign) = f.integer_decode(); |
1810 | 0 | let exp_u64 = exp as u16 as u64; |
1811 | 0 | let sign_u64 = (sign > 0) as u64; |
1812 | 0 | (man & MAN_MASK) | ((exp_u64 << 52) & EXP_MASK) | ((sign_u64 << 63) & SIGN_MASK) |
1813 | 0 | } |
1814 | | |
1815 | | impl<T: FloatCore> Zero for NotNan<T> { |
1816 | | #[inline] |
1817 | 0 | fn zero() -> Self { |
1818 | 0 | NotNan(T::zero()) |
1819 | 0 | } |
1820 | | |
1821 | | #[inline] |
1822 | 0 | fn is_zero(&self) -> bool { |
1823 | 0 | self.0.is_zero() |
1824 | 0 | } |
1825 | | } |
1826 | | |
1827 | | impl<T: FloatCore> One for NotNan<T> { |
1828 | | #[inline] |
1829 | 0 | fn one() -> Self { |
1830 | 0 | NotNan(T::one()) |
1831 | 0 | } |
1832 | | } |
1833 | | |
1834 | | impl<T: FloatCore> Bounded for NotNan<T> { |
1835 | | #[inline] |
1836 | 0 | fn min_value() -> Self { |
1837 | 0 | NotNan(T::min_value()) |
1838 | 0 | } |
1839 | | |
1840 | | #[inline] |
1841 | 0 | fn max_value() -> Self { |
1842 | 0 | NotNan(T::max_value()) |
1843 | 0 | } |
1844 | | } |
1845 | | |
1846 | | impl<T: FloatCore + FromStr> FromStr for NotNan<T> { |
1847 | | type Err = ParseNotNanError<T::Err>; |
1848 | | |
1849 | | /// Convert a &str to `NotNan`. Returns an error if the string fails to parse, |
1850 | | /// or if the resulting value is NaN |
1851 | | /// |
1852 | | /// ``` |
1853 | | /// use ordered_float::NotNan; |
1854 | | /// |
1855 | | /// assert!("-10".parse::<NotNan<f32>>().is_ok()); |
1856 | | /// assert!("abc".parse::<NotNan<f32>>().is_err()); |
1857 | | /// assert!("NaN".parse::<NotNan<f32>>().is_err()); |
1858 | | /// ``` |
1859 | 0 | fn from_str(src: &str) -> Result<Self, Self::Err> { |
1860 | 0 | src.parse() |
1861 | 0 | .map_err(ParseNotNanError::ParseFloatError) |
1862 | 0 | .and_then(|f| NotNan::new(f).map_err(|_| ParseNotNanError::IsNaN)) |
1863 | 0 | } |
1864 | | } |
1865 | | |
1866 | | impl<T: FloatCore + FromPrimitive> FromPrimitive for NotNan<T> { |
1867 | 0 | fn from_i64(n: i64) -> Option<Self> { |
1868 | 0 | T::from_i64(n).and_then(|n| NotNan::new(n).ok()) |
1869 | 0 | } |
1870 | 0 | fn from_u64(n: u64) -> Option<Self> { |
1871 | 0 | T::from_u64(n).and_then(|n| NotNan::new(n).ok()) |
1872 | 0 | } |
1873 | | |
1874 | 0 | fn from_isize(n: isize) -> Option<Self> { |
1875 | 0 | T::from_isize(n).and_then(|n| NotNan::new(n).ok()) |
1876 | 0 | } |
1877 | 0 | fn from_i8(n: i8) -> Option<Self> { |
1878 | 0 | T::from_i8(n).and_then(|n| NotNan::new(n).ok()) |
1879 | 0 | } |
1880 | 0 | fn from_i16(n: i16) -> Option<Self> { |
1881 | 0 | T::from_i16(n).and_then(|n| NotNan::new(n).ok()) |
1882 | 0 | } |
1883 | 0 | fn from_i32(n: i32) -> Option<Self> { |
1884 | 0 | T::from_i32(n).and_then(|n| NotNan::new(n).ok()) |
1885 | 0 | } |
1886 | 0 | fn from_usize(n: usize) -> Option<Self> { |
1887 | 0 | T::from_usize(n).and_then(|n| NotNan::new(n).ok()) |
1888 | 0 | } |
1889 | 0 | fn from_u8(n: u8) -> Option<Self> { |
1890 | 0 | T::from_u8(n).and_then(|n| NotNan::new(n).ok()) |
1891 | 0 | } |
1892 | 0 | fn from_u16(n: u16) -> Option<Self> { |
1893 | 0 | T::from_u16(n).and_then(|n| NotNan::new(n).ok()) |
1894 | 0 | } |
1895 | 0 | fn from_u32(n: u32) -> Option<Self> { |
1896 | 0 | T::from_u32(n).and_then(|n| NotNan::new(n).ok()) |
1897 | 0 | } |
1898 | 0 | fn from_f32(n: f32) -> Option<Self> { |
1899 | 0 | T::from_f32(n).and_then(|n| NotNan::new(n).ok()) |
1900 | 0 | } |
1901 | 0 | fn from_f64(n: f64) -> Option<Self> { |
1902 | 0 | T::from_f64(n).and_then(|n| NotNan::new(n).ok()) |
1903 | 0 | } |
1904 | | } |
1905 | | |
1906 | | impl<T: FloatCore> ToPrimitive for NotNan<T> { |
1907 | 0 | fn to_i64(&self) -> Option<i64> { |
1908 | 0 | self.0.to_i64() |
1909 | 0 | } |
1910 | 0 | fn to_u64(&self) -> Option<u64> { |
1911 | 0 | self.0.to_u64() |
1912 | 0 | } |
1913 | | |
1914 | 0 | fn to_isize(&self) -> Option<isize> { |
1915 | 0 | self.0.to_isize() |
1916 | 0 | } |
1917 | 0 | fn to_i8(&self) -> Option<i8> { |
1918 | 0 | self.0.to_i8() |
1919 | 0 | } |
1920 | 0 | fn to_i16(&self) -> Option<i16> { |
1921 | 0 | self.0.to_i16() |
1922 | 0 | } |
1923 | 0 | fn to_i32(&self) -> Option<i32> { |
1924 | 0 | self.0.to_i32() |
1925 | 0 | } |
1926 | 0 | fn to_usize(&self) -> Option<usize> { |
1927 | 0 | self.0.to_usize() |
1928 | 0 | } |
1929 | 0 | fn to_u8(&self) -> Option<u8> { |
1930 | 0 | self.0.to_u8() |
1931 | 0 | } |
1932 | 0 | fn to_u16(&self) -> Option<u16> { |
1933 | 0 | self.0.to_u16() |
1934 | 0 | } |
1935 | 0 | fn to_u32(&self) -> Option<u32> { |
1936 | 0 | self.0.to_u32() |
1937 | 0 | } |
1938 | 0 | fn to_f32(&self) -> Option<f32> { |
1939 | 0 | self.0.to_f32() |
1940 | 0 | } |
1941 | 0 | fn to_f64(&self) -> Option<f64> { |
1942 | 0 | self.0.to_f64() |
1943 | 0 | } |
1944 | | } |
1945 | | |
1946 | | /// An error indicating a parse error from a string for `NotNan`. |
1947 | | #[derive(Copy, Clone, PartialEq, Eq, Debug)] |
1948 | | pub enum ParseNotNanError<E> { |
1949 | | /// A plain parse error from the underlying float type. |
1950 | | ParseFloatError(E), |
1951 | | /// The parsed float value resulted in a NaN. |
1952 | | IsNaN, |
1953 | | } |
1954 | | |
1955 | | #[cfg(feature = "std")] |
1956 | | impl<E: fmt::Debug + Error + 'static> Error for ParseNotNanError<E> { |
1957 | 0 | fn description(&self) -> &str { |
1958 | 0 | "Error parsing a not-NaN floating point value" |
1959 | 0 | } |
1960 | | |
1961 | 0 | fn source(&self) -> Option<&(dyn Error + 'static)> { |
1962 | 0 | match self { |
1963 | 0 | ParseNotNanError::ParseFloatError(e) => Some(e), |
1964 | 0 | ParseNotNanError::IsNaN => None, |
1965 | | } |
1966 | 0 | } |
1967 | | } |
1968 | | |
1969 | | impl<E: fmt::Display> fmt::Display for ParseNotNanError<E> { |
1970 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1971 | 0 | match self { |
1972 | 0 | ParseNotNanError::ParseFloatError(e) => write!(f, "Parse error: {}", e), |
1973 | 0 | ParseNotNanError::IsNaN => write!(f, "NotNan parser encounter a NaN"), |
1974 | | } |
1975 | 0 | } |
1976 | | } |
1977 | | |
1978 | | impl<T: FloatCore> Num for NotNan<T> { |
1979 | | type FromStrRadixErr = ParseNotNanError<T::FromStrRadixErr>; |
1980 | | |
1981 | 0 | fn from_str_radix(src: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> { |
1982 | 0 | T::from_str_radix(src, radix) |
1983 | 0 | .map_err(ParseNotNanError::ParseFloatError) |
1984 | 0 | .and_then(|n| NotNan::new(n).map_err(|_| ParseNotNanError::IsNaN)) |
1985 | 0 | } |
1986 | | } |
1987 | | |
1988 | | impl<T: FloatCore + Signed> Signed for NotNan<T> { |
1989 | | #[inline] |
1990 | 0 | fn abs(&self) -> Self { |
1991 | 0 | NotNan(self.0.abs()) |
1992 | 0 | } |
1993 | | |
1994 | 0 | fn abs_sub(&self, other: &Self) -> Self { |
1995 | 0 | NotNan::new(Signed::abs_sub(&self.0, &other.0)).expect("Subtraction resulted in NaN") |
1996 | 0 | } |
1997 | | |
1998 | | #[inline] |
1999 | 0 | fn signum(&self) -> Self { |
2000 | 0 | NotNan(self.0.signum()) |
2001 | 0 | } |
2002 | | #[inline] |
2003 | 0 | fn is_positive(&self) -> bool { |
2004 | 0 | self.0.is_positive() |
2005 | 0 | } |
2006 | | #[inline] |
2007 | 0 | fn is_negative(&self) -> bool { |
2008 | 0 | self.0.is_negative() |
2009 | 0 | } |
2010 | | } |
2011 | | |
2012 | | impl<T: FloatCore> NumCast for NotNan<T> { |
2013 | 0 | fn from<F: ToPrimitive>(n: F) -> Option<Self> { |
2014 | 0 | T::from(n).and_then(|n| NotNan::new(n).ok()) |
2015 | 0 | } |
2016 | | } |
2017 | | |
2018 | | macro_rules! impl_float_const_method { |
2019 | | ($wrapper:expr, $method:ident) => { |
2020 | | #[allow(non_snake_case)] |
2021 | | #[allow(clippy::redundant_closure_call)] |
2022 | 0 | fn $method() -> Self { |
2023 | 0 | $wrapper(T::$method()) |
2024 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::FRAC_1_SQRT_2 Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::FRAC_2_SQRT_PI Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::E Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::PI Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::LN_2 Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::LN_10 Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::LOG2_E Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::SQRT_2 Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::LOG10_E Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::FRAC_1_PI Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::FRAC_2_PI Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::FRAC_PI_2 Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::FRAC_PI_3 Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::FRAC_PI_4 Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::FRAC_PI_6 Unexecuted instantiation: <ordered_float::OrderedFloat<_> as num_traits::float::FloatConst>::FRAC_PI_8 Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_1_SQRT_2 Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_2_SQRT_PI Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::E Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::PI Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::LN_2 Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::LN_10 Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::LOG2_E Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::SQRT_2 Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::LOG10_E Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_1_PI Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_2_PI Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_PI_2 Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_PI_3 Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_PI_4 Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_PI_6 Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_PI_8 |
2025 | | }; |
2026 | | } |
2027 | | |
2028 | | macro_rules! impl_float_const { |
2029 | | ($type:ident, $wrapper:expr) => { |
2030 | | impl<T: FloatConst> FloatConst for $type<T> { |
2031 | | impl_float_const_method!($wrapper, E); |
2032 | | impl_float_const_method!($wrapper, FRAC_1_PI); |
2033 | | impl_float_const_method!($wrapper, FRAC_1_SQRT_2); |
2034 | | impl_float_const_method!($wrapper, FRAC_2_PI); |
2035 | | impl_float_const_method!($wrapper, FRAC_2_SQRT_PI); |
2036 | | impl_float_const_method!($wrapper, FRAC_PI_2); |
2037 | | impl_float_const_method!($wrapper, FRAC_PI_3); |
2038 | | impl_float_const_method!($wrapper, FRAC_PI_4); |
2039 | | impl_float_const_method!($wrapper, FRAC_PI_6); |
2040 | | impl_float_const_method!($wrapper, FRAC_PI_8); |
2041 | | impl_float_const_method!($wrapper, LN_10); |
2042 | | impl_float_const_method!($wrapper, LN_2); |
2043 | | impl_float_const_method!($wrapper, LOG10_E); |
2044 | | impl_float_const_method!($wrapper, LOG2_E); |
2045 | | impl_float_const_method!($wrapper, PI); |
2046 | | impl_float_const_method!($wrapper, SQRT_2); |
2047 | | } |
2048 | | }; |
2049 | | } |
2050 | | |
2051 | | impl_float_const!(OrderedFloat, OrderedFloat); |
2052 | | // Float constants are not NaN. |
2053 | 0 | impl_float_const!(NotNan, |x| unsafe { NotNan::new_unchecked(x) });Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_1_SQRT_2::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_2_SQRT_PI::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::E::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::PI::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::LN_2::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::LN_10::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::LOG2_E::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::SQRT_2::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::LOG10_E::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_1_PI::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_2_PI::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_PI_2::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_PI_3::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_PI_4::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_PI_6::{closure#0}Unexecuted instantiation: <ordered_float::NotNan<_> as num_traits::float::FloatConst>::FRAC_PI_8::{closure#0} |
2054 | | |
2055 | | #[cfg(feature = "serde")] |
2056 | | mod impl_serde { |
2057 | | extern crate serde; |
2058 | | use self::serde::de::{Error, Unexpected}; |
2059 | | use self::serde::{Deserialize, Deserializer, Serialize, Serializer}; |
2060 | | use super::{NotNan, OrderedFloat}; |
2061 | | use core::f64; |
2062 | | use num_traits::float::FloatCore; |
2063 | | |
2064 | | #[cfg(test)] |
2065 | | extern crate serde_test; |
2066 | | #[cfg(test)] |
2067 | | use self::serde_test::{assert_de_tokens_error, assert_tokens, Token}; |
2068 | | |
2069 | | impl<T: FloatCore + Serialize> Serialize for OrderedFloat<T> { |
2070 | | #[inline] |
2071 | | fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> { |
2072 | | self.0.serialize(s) |
2073 | | } |
2074 | | } |
2075 | | |
2076 | | impl<'de, T: FloatCore + Deserialize<'de>> Deserialize<'de> for OrderedFloat<T> { |
2077 | | #[inline] |
2078 | | fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> { |
2079 | | T::deserialize(d).map(OrderedFloat) |
2080 | | } |
2081 | | } |
2082 | | |
2083 | | impl<T: FloatCore + Serialize> Serialize for NotNan<T> { |
2084 | | #[inline] |
2085 | | fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> { |
2086 | | self.0.serialize(s) |
2087 | | } |
2088 | | } |
2089 | | |
2090 | | impl<'de, T: FloatCore + Deserialize<'de>> Deserialize<'de> for NotNan<T> { |
2091 | | fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> { |
2092 | | let float = T::deserialize(d)?; |
2093 | | NotNan::new(float).map_err(|_| { |
2094 | | Error::invalid_value(Unexpected::Float(f64::NAN), &"float (but not NaN)") |
2095 | | }) |
2096 | | } |
2097 | | } |
2098 | | |
2099 | | #[test] |
2100 | | fn test_ordered_float() { |
2101 | | let float = OrderedFloat(1.0f64); |
2102 | | assert_tokens(&float, &[Token::F64(1.0)]); |
2103 | | } |
2104 | | |
2105 | | #[test] |
2106 | | fn test_not_nan() { |
2107 | | let float = NotNan(1.0f64); |
2108 | | assert_tokens(&float, &[Token::F64(1.0)]); |
2109 | | } |
2110 | | |
2111 | | #[test] |
2112 | | fn test_fail_on_nan() { |
2113 | | assert_de_tokens_error::<NotNan<f64>>( |
2114 | | &[Token::F64(f64::NAN)], |
2115 | | "invalid value: floating point `NaN`, expected float (but not NaN)", |
2116 | | ); |
2117 | | } |
2118 | | } |
2119 | | |
2120 | | #[cfg(any(feature = "rkyv_16", feature = "rkyv_32", feature = "rkyv_64"))] |
2121 | | mod impl_rkyv { |
2122 | | use super::{NotNan, OrderedFloat}; |
2123 | | use num_traits::float::FloatCore; |
2124 | | #[cfg(test)] |
2125 | | use rkyv::{archived_root, ser::Serializer}; |
2126 | | use rkyv::{Archive, Deserialize, Fallible, Serialize}; |
2127 | | |
2128 | | #[cfg(test)] |
2129 | | type DefaultSerializer = rkyv::ser::serializers::CoreSerializer<16, 16>; |
2130 | | #[cfg(test)] |
2131 | | type DefaultDeserializer = rkyv::Infallible; |
2132 | | |
2133 | | impl<T: FloatCore + Archive> Archive for OrderedFloat<T> { |
2134 | | type Archived = OrderedFloat<T::Archived>; |
2135 | | |
2136 | | type Resolver = T::Resolver; |
2137 | | |
2138 | | unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) { |
2139 | | self.0.resolve(pos, resolver, out.cast()) |
2140 | | } |
2141 | | } |
2142 | | |
2143 | | impl<T: FloatCore + Serialize<S>, S: Fallible + ?Sized> Serialize<S> for OrderedFloat<T> { |
2144 | | fn serialize(&self, s: &mut S) -> Result<Self::Resolver, S::Error> { |
2145 | | self.0.serialize(s) |
2146 | | } |
2147 | | } |
2148 | | |
2149 | | impl<T: FloatCore, AT: Deserialize<T, D>, D: Fallible + ?Sized> Deserialize<OrderedFloat<T>, D> |
2150 | | for OrderedFloat<AT> |
2151 | | { |
2152 | | fn deserialize(&self, d: &mut D) -> Result<OrderedFloat<T>, D::Error> { |
2153 | | self.0.deserialize(d).map(OrderedFloat) |
2154 | | } |
2155 | | } |
2156 | | |
2157 | | impl<T: FloatCore + Archive> Archive for NotNan<T> { |
2158 | | type Archived = NotNan<T::Archived>; |
2159 | | |
2160 | | type Resolver = T::Resolver; |
2161 | | |
2162 | | unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived) { |
2163 | | self.0.resolve(pos, resolver, out.cast()) |
2164 | | } |
2165 | | } |
2166 | | |
2167 | | impl<T: FloatCore + Serialize<S>, S: Fallible + ?Sized> Serialize<S> for NotNan<T> { |
2168 | | fn serialize(&self, s: &mut S) -> Result<Self::Resolver, S::Error> { |
2169 | | self.0.serialize(s) |
2170 | | } |
2171 | | } |
2172 | | |
2173 | | impl<T: FloatCore, AT: Deserialize<T, D>, D: Fallible + ?Sized> Deserialize<NotNan<T>, D> |
2174 | | for NotNan<AT> |
2175 | | { |
2176 | | fn deserialize(&self, d: &mut D) -> Result<NotNan<T>, D::Error> { |
2177 | | self.0.deserialize(d).map(NotNan) |
2178 | | } |
2179 | | } |
2180 | | |
2181 | | macro_rules! rkyv_eq_ord { |
2182 | | ($main:ident, $float:ty, $rend:ty) => { |
2183 | | impl PartialEq<$main<$float>> for $main<$rend> { |
2184 | | fn eq(&self, other: &$main<$float>) -> bool { |
2185 | | other.eq(&self.0.value()) |
2186 | | } |
2187 | | } |
2188 | | impl PartialEq<$main<$rend>> for $main<$float> { |
2189 | | fn eq(&self, other: &$main<$rend>) -> bool { |
2190 | | self.eq(&other.0.value()) |
2191 | | } |
2192 | | } |
2193 | | |
2194 | | impl PartialOrd<$main<$float>> for $main<$rend> { |
2195 | | fn partial_cmp(&self, other: &$main<$float>) -> Option<core::cmp::Ordering> { |
2196 | | self.0.value().partial_cmp(other) |
2197 | | } |
2198 | | } |
2199 | | |
2200 | | impl PartialOrd<$main<$rend>> for $main<$float> { |
2201 | | fn partial_cmp(&self, other: &$main<$rend>) -> Option<core::cmp::Ordering> { |
2202 | | other |
2203 | | .0 |
2204 | | .value() |
2205 | | .partial_cmp(self) |
2206 | | .map(core::cmp::Ordering::reverse) |
2207 | | } |
2208 | | } |
2209 | | }; |
2210 | | } |
2211 | | |
2212 | | rkyv_eq_ord! { OrderedFloat, f32, rkyv::rend::f32_le } |
2213 | | rkyv_eq_ord! { OrderedFloat, f32, rkyv::rend::f32_be } |
2214 | | rkyv_eq_ord! { OrderedFloat, f64, rkyv::rend::f64_le } |
2215 | | rkyv_eq_ord! { OrderedFloat, f64, rkyv::rend::f64_be } |
2216 | | rkyv_eq_ord! { NotNan, f32, rkyv::rend::f32_le } |
2217 | | rkyv_eq_ord! { NotNan, f32, rkyv::rend::f32_be } |
2218 | | rkyv_eq_ord! { NotNan, f64, rkyv::rend::f64_le } |
2219 | | rkyv_eq_ord! { NotNan, f64, rkyv::rend::f64_be } |
2220 | | |
2221 | | #[cfg(feature = "rkyv_ck")] |
2222 | | use super::FloatIsNan; |
2223 | | #[cfg(feature = "rkyv_ck")] |
2224 | | use core::convert::Infallible; |
2225 | | #[cfg(feature = "rkyv_ck")] |
2226 | | use rkyv::bytecheck::CheckBytes; |
2227 | | |
2228 | | #[cfg(feature = "rkyv_ck")] |
2229 | | impl<C: ?Sized, T: FloatCore + CheckBytes<C>> CheckBytes<C> for OrderedFloat<T> { |
2230 | | type Error = Infallible; |
2231 | | |
2232 | | #[inline] |
2233 | | unsafe fn check_bytes<'a>(value: *const Self, _: &mut C) -> Result<&'a Self, Self::Error> { |
2234 | | Ok(&*value) |
2235 | | } |
2236 | | } |
2237 | | |
2238 | | #[cfg(feature = "rkyv_ck")] |
2239 | | impl<C: ?Sized, T: FloatCore + CheckBytes<C>> CheckBytes<C> for NotNan<T> { |
2240 | | type Error = FloatIsNan; |
2241 | | |
2242 | | #[inline] |
2243 | | unsafe fn check_bytes<'a>(value: *const Self, _: &mut C) -> Result<&'a Self, Self::Error> { |
2244 | | Self::new(*(value as *const T)).map(|_| &*value) |
2245 | | } |
2246 | | } |
2247 | | |
2248 | | #[test] |
2249 | | fn test_ordered_float() { |
2250 | | let float = OrderedFloat(1.0f64); |
2251 | | let mut serializer = DefaultSerializer::default(); |
2252 | | serializer |
2253 | | .serialize_value(&float) |
2254 | | .expect("failed to archive value"); |
2255 | | let len = serializer.pos(); |
2256 | | let buffer = serializer.into_serializer().into_inner(); |
2257 | | |
2258 | | let archived_value = unsafe { archived_root::<OrderedFloat<f64>>(&buffer[0..len]) }; |
2259 | | assert_eq!(archived_value, &float); |
2260 | | let mut deserializer = DefaultDeserializer::default(); |
2261 | | let deser_float: OrderedFloat<f64> = archived_value.deserialize(&mut deserializer).unwrap(); |
2262 | | assert_eq!(deser_float, float); |
2263 | | } |
2264 | | |
2265 | | #[test] |
2266 | | fn test_not_nan() { |
2267 | | let float = NotNan(1.0f64); |
2268 | | let mut serializer = DefaultSerializer::default(); |
2269 | | serializer |
2270 | | .serialize_value(&float) |
2271 | | .expect("failed to archive value"); |
2272 | | let len = serializer.pos(); |
2273 | | let buffer = serializer.into_serializer().into_inner(); |
2274 | | |
2275 | | let archived_value = unsafe { archived_root::<NotNan<f64>>(&buffer[0..len]) }; |
2276 | | assert_eq!(archived_value, &float); |
2277 | | let mut deserializer = DefaultDeserializer::default(); |
2278 | | let deser_float: NotNan<f64> = archived_value.deserialize(&mut deserializer).unwrap(); |
2279 | | assert_eq!(deser_float, float); |
2280 | | } |
2281 | | } |
2282 | | |
2283 | | #[cfg(feature = "speedy")] |
2284 | | mod impl_speedy { |
2285 | | use super::{NotNan, OrderedFloat}; |
2286 | | use num_traits::float::FloatCore; |
2287 | | use speedy::{Context, Readable, Reader, Writable, Writer}; |
2288 | | |
2289 | | impl<C, T> Writable<C> for OrderedFloat<T> |
2290 | | where |
2291 | | C: Context, |
2292 | | T: Writable<C>, |
2293 | | { |
2294 | | fn write_to<W: ?Sized + Writer<C>>(&self, writer: &mut W) -> Result<(), C::Error> { |
2295 | | self.0.write_to(writer) |
2296 | | } |
2297 | | |
2298 | | fn bytes_needed(&self) -> Result<usize, C::Error> { |
2299 | | self.0.bytes_needed() |
2300 | | } |
2301 | | } |
2302 | | |
2303 | | impl<C, T> Writable<C> for NotNan<T> |
2304 | | where |
2305 | | C: Context, |
2306 | | T: Writable<C>, |
2307 | | { |
2308 | | fn write_to<W: ?Sized + Writer<C>>(&self, writer: &mut W) -> Result<(), C::Error> { |
2309 | | self.0.write_to(writer) |
2310 | | } |
2311 | | |
2312 | | fn bytes_needed(&self) -> Result<usize, C::Error> { |
2313 | | self.0.bytes_needed() |
2314 | | } |
2315 | | } |
2316 | | |
2317 | | impl<'a, T, C: Context> Readable<'a, C> for OrderedFloat<T> |
2318 | | where |
2319 | | T: Readable<'a, C>, |
2320 | | { |
2321 | | fn read_from<R: Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> { |
2322 | | T::read_from(reader).map(OrderedFloat) |
2323 | | } |
2324 | | |
2325 | | fn minimum_bytes_needed() -> usize { |
2326 | | T::minimum_bytes_needed() |
2327 | | } |
2328 | | } |
2329 | | |
2330 | | impl<'a, T: FloatCore, C: Context> Readable<'a, C> for NotNan<T> |
2331 | | where |
2332 | | T: Readable<'a, C>, |
2333 | | { |
2334 | | fn read_from<R: Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> { |
2335 | | let value: T = reader.read_value()?; |
2336 | | Self::new(value).map_err(|error| { |
2337 | | speedy::Error::custom(std::format!("failed to read NotNan: {}", error)).into() |
2338 | | }) |
2339 | | } |
2340 | | |
2341 | | fn minimum_bytes_needed() -> usize { |
2342 | | T::minimum_bytes_needed() |
2343 | | } |
2344 | | } |
2345 | | |
2346 | | #[test] |
2347 | | fn test_ordered_float() { |
2348 | | let float = OrderedFloat(1.0f64); |
2349 | | let buffer = float.write_to_vec().unwrap(); |
2350 | | let deser_float: OrderedFloat<f64> = OrderedFloat::read_from_buffer(&buffer).unwrap(); |
2351 | | assert_eq!(deser_float, float); |
2352 | | } |
2353 | | |
2354 | | #[test] |
2355 | | fn test_not_nan() { |
2356 | | let float = NotNan(1.0f64); |
2357 | | let buffer = float.write_to_vec().unwrap(); |
2358 | | let deser_float: NotNan<f64> = NotNan::read_from_buffer(&buffer).unwrap(); |
2359 | | assert_eq!(deser_float, float); |
2360 | | } |
2361 | | |
2362 | | #[test] |
2363 | | fn test_not_nan_with_nan() { |
2364 | | let nan_buf = f64::nan().write_to_vec().unwrap(); |
2365 | | let nan_err: Result<NotNan<f64>, _> = NotNan::read_from_buffer(&nan_buf); |
2366 | | assert!(nan_err.is_err()); |
2367 | | } |
2368 | | } |
2369 | | |
2370 | | #[cfg(feature = "borsh")] |
2371 | | mod impl_borsh { |
2372 | | extern crate borsh; |
2373 | | use super::{NotNan, OrderedFloat}; |
2374 | | use num_traits::float::FloatCore; |
2375 | | |
2376 | | impl<T> borsh::BorshSerialize for OrderedFloat<T> |
2377 | | where |
2378 | | T: borsh::BorshSerialize, |
2379 | | { |
2380 | | #[inline] |
2381 | | fn serialize<W: borsh::io::Write>(&self, writer: &mut W) -> borsh::io::Result<()> { |
2382 | | <T as borsh::BorshSerialize>::serialize(&self.0, writer) |
2383 | | } |
2384 | | } |
2385 | | |
2386 | | impl<T> borsh::BorshDeserialize for OrderedFloat<T> |
2387 | | where |
2388 | | T: borsh::BorshDeserialize, |
2389 | | { |
2390 | | #[inline] |
2391 | | fn deserialize_reader<R: borsh::io::Read>(reader: &mut R) -> borsh::io::Result<Self> { |
2392 | | <T as borsh::BorshDeserialize>::deserialize_reader(reader).map(Self) |
2393 | | } |
2394 | | } |
2395 | | |
2396 | | impl<T> borsh::BorshSerialize for NotNan<T> |
2397 | | where |
2398 | | T: borsh::BorshSerialize, |
2399 | | { |
2400 | | #[inline] |
2401 | | fn serialize<W: borsh::io::Write>(&self, writer: &mut W) -> borsh::io::Result<()> { |
2402 | | <T as borsh::BorshSerialize>::serialize(&self.0, writer) |
2403 | | } |
2404 | | } |
2405 | | |
2406 | | impl<T> borsh::BorshDeserialize for NotNan<T> |
2407 | | where |
2408 | | T: FloatCore + borsh::BorshDeserialize, |
2409 | | { |
2410 | | #[inline] |
2411 | | fn deserialize_reader<R: borsh::io::Read>(reader: &mut R) -> borsh::io::Result<Self> { |
2412 | | let float = <T as borsh::BorshDeserialize>::deserialize_reader(reader)?; |
2413 | | NotNan::new(float).map_err(|_| { |
2414 | | borsh::io::Error::new( |
2415 | | borsh::io::ErrorKind::InvalidData, |
2416 | | "expected a non-NaN float", |
2417 | | ) |
2418 | | }) |
2419 | | } |
2420 | | } |
2421 | | |
2422 | | #[test] |
2423 | | fn test_ordered_float() { |
2424 | | let float = crate::OrderedFloat(1.0f64); |
2425 | | let buffer = borsh::to_vec(&float).expect("failed to serialize value"); |
2426 | | let deser_float: crate::OrderedFloat<f64> = |
2427 | | borsh::from_slice(&buffer).expect("failed to deserialize value"); |
2428 | | assert_eq!(deser_float, float); |
2429 | | } |
2430 | | |
2431 | | #[test] |
2432 | | fn test_not_nan() { |
2433 | | let float = crate::NotNan(1.0f64); |
2434 | | let buffer = borsh::to_vec(&float).expect("failed to serialize value"); |
2435 | | let deser_float: crate::NotNan<f64> = |
2436 | | borsh::from_slice(&buffer).expect("failed to deserialize value"); |
2437 | | assert_eq!(deser_float, float); |
2438 | | } |
2439 | | } |
2440 | | |
2441 | | #[cfg(all(feature = "std", feature = "schemars"))] |
2442 | | mod impl_schemars { |
2443 | | extern crate schemars; |
2444 | | use self::schemars::gen::SchemaGenerator; |
2445 | | use self::schemars::schema::{InstanceType, Schema, SchemaObject}; |
2446 | | use super::{NotNan, OrderedFloat}; |
2447 | | |
2448 | | macro_rules! primitive_float_impl { |
2449 | | ($type:ty, $schema_name:literal) => { |
2450 | | impl schemars::JsonSchema for $type { |
2451 | | fn is_referenceable() -> bool { |
2452 | | false |
2453 | | } |
2454 | | |
2455 | | fn schema_name() -> std::string::String { |
2456 | | std::string::String::from($schema_name) |
2457 | | } |
2458 | | |
2459 | | fn json_schema(_: &mut SchemaGenerator) -> Schema { |
2460 | | SchemaObject { |
2461 | | instance_type: Some(InstanceType::Number.into()), |
2462 | | format: Some(std::string::String::from($schema_name)), |
2463 | | ..Default::default() |
2464 | | } |
2465 | | .into() |
2466 | | } |
2467 | | } |
2468 | | }; |
2469 | | } |
2470 | | |
2471 | | primitive_float_impl!(OrderedFloat<f32>, "float"); |
2472 | | primitive_float_impl!(OrderedFloat<f64>, "double"); |
2473 | | primitive_float_impl!(NotNan<f32>, "float"); |
2474 | | primitive_float_impl!(NotNan<f64>, "double"); |
2475 | | |
2476 | | #[test] |
2477 | | fn schema_generation_does_not_panic_for_common_floats() { |
2478 | | { |
2479 | | let schema = schemars::gen::SchemaGenerator::default() |
2480 | | .into_root_schema_for::<OrderedFloat<f32>>(); |
2481 | | assert_eq!( |
2482 | | schema.schema.instance_type, |
2483 | | Some(schemars::schema::SingleOrVec::Single(std::boxed::Box::new( |
2484 | | schemars::schema::InstanceType::Number |
2485 | | ))) |
2486 | | ); |
2487 | | assert_eq!( |
2488 | | schema.schema.metadata.unwrap().title.unwrap(), |
2489 | | std::string::String::from("float") |
2490 | | ); |
2491 | | } |
2492 | | { |
2493 | | let schema = schemars::gen::SchemaGenerator::default() |
2494 | | .into_root_schema_for::<OrderedFloat<f64>>(); |
2495 | | assert_eq!( |
2496 | | schema.schema.instance_type, |
2497 | | Some(schemars::schema::SingleOrVec::Single(std::boxed::Box::new( |
2498 | | schemars::schema::InstanceType::Number |
2499 | | ))) |
2500 | | ); |
2501 | | assert_eq!( |
2502 | | schema.schema.metadata.unwrap().title.unwrap(), |
2503 | | std::string::String::from("double") |
2504 | | ); |
2505 | | } |
2506 | | { |
2507 | | let schema = |
2508 | | schemars::gen::SchemaGenerator::default().into_root_schema_for::<NotNan<f32>>(); |
2509 | | assert_eq!( |
2510 | | schema.schema.instance_type, |
2511 | | Some(schemars::schema::SingleOrVec::Single(std::boxed::Box::new( |
2512 | | schemars::schema::InstanceType::Number |
2513 | | ))) |
2514 | | ); |
2515 | | assert_eq!( |
2516 | | schema.schema.metadata.unwrap().title.unwrap(), |
2517 | | std::string::String::from("float") |
2518 | | ); |
2519 | | } |
2520 | | { |
2521 | | let schema = |
2522 | | schemars::gen::SchemaGenerator::default().into_root_schema_for::<NotNan<f64>>(); |
2523 | | assert_eq!( |
2524 | | schema.schema.instance_type, |
2525 | | Some(schemars::schema::SingleOrVec::Single(std::boxed::Box::new( |
2526 | | schemars::schema::InstanceType::Number |
2527 | | ))) |
2528 | | ); |
2529 | | assert_eq!( |
2530 | | schema.schema.metadata.unwrap().title.unwrap(), |
2531 | | std::string::String::from("double") |
2532 | | ); |
2533 | | } |
2534 | | } |
2535 | | #[test] |
2536 | | fn ordered_float_schema_match_primitive_schema() { |
2537 | | { |
2538 | | let of_schema = schemars::gen::SchemaGenerator::default() |
2539 | | .into_root_schema_for::<OrderedFloat<f32>>(); |
2540 | | let prim_schema = |
2541 | | schemars::gen::SchemaGenerator::default().into_root_schema_for::<f32>(); |
2542 | | assert_eq!(of_schema, prim_schema); |
2543 | | } |
2544 | | { |
2545 | | let of_schema = schemars::gen::SchemaGenerator::default() |
2546 | | .into_root_schema_for::<OrderedFloat<f64>>(); |
2547 | | let prim_schema = |
2548 | | schemars::gen::SchemaGenerator::default().into_root_schema_for::<f64>(); |
2549 | | assert_eq!(of_schema, prim_schema); |
2550 | | } |
2551 | | { |
2552 | | let of_schema = |
2553 | | schemars::gen::SchemaGenerator::default().into_root_schema_for::<NotNan<f32>>(); |
2554 | | let prim_schema = |
2555 | | schemars::gen::SchemaGenerator::default().into_root_schema_for::<f32>(); |
2556 | | assert_eq!(of_schema, prim_schema); |
2557 | | } |
2558 | | { |
2559 | | let of_schema = |
2560 | | schemars::gen::SchemaGenerator::default().into_root_schema_for::<NotNan<f64>>(); |
2561 | | let prim_schema = |
2562 | | schemars::gen::SchemaGenerator::default().into_root_schema_for::<f64>(); |
2563 | | assert_eq!(of_schema, prim_schema); |
2564 | | } |
2565 | | } |
2566 | | } |
2567 | | |
2568 | | #[cfg(feature = "rand")] |
2569 | | mod impl_rand { |
2570 | | use super::{NotNan, OrderedFloat}; |
2571 | | use rand::distributions::uniform::*; |
2572 | | use rand::distributions::{Distribution, Open01, OpenClosed01, Standard}; |
2573 | | use rand::Rng; |
2574 | | |
2575 | | macro_rules! impl_distribution { |
2576 | | ($dist:ident, $($f:ty),+) => { |
2577 | | $( |
2578 | | impl Distribution<NotNan<$f>> for $dist { |
2579 | | fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> NotNan<$f> { |
2580 | | // 'rand' never generates NaN values in the Standard, Open01, or |
2581 | | // OpenClosed01 distributions. Using 'new_unchecked' is therefore |
2582 | | // safe. |
2583 | | unsafe { NotNan::new_unchecked(self.sample(rng)) } |
2584 | | } |
2585 | | } |
2586 | | |
2587 | | impl Distribution<OrderedFloat<$f>> for $dist { |
2588 | | fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> OrderedFloat<$f> { |
2589 | | OrderedFloat(self.sample(rng)) |
2590 | | } |
2591 | | } |
2592 | | )* |
2593 | | } |
2594 | | } |
2595 | | |
2596 | | impl_distribution! { Standard, f32, f64 } |
2597 | | impl_distribution! { Open01, f32, f64 } |
2598 | | impl_distribution! { OpenClosed01, f32, f64 } |
2599 | | |
2600 | | /// A sampler for a uniform distribution |
2601 | | #[derive(Clone, Copy, Debug)] |
2602 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
2603 | | pub struct UniformNotNan<T>(UniformFloat<T>); |
2604 | | impl SampleUniform for NotNan<f32> { |
2605 | | type Sampler = UniformNotNan<f32>; |
2606 | | } |
2607 | | impl SampleUniform for NotNan<f64> { |
2608 | | type Sampler = UniformNotNan<f64>; |
2609 | | } |
2610 | | impl<T> PartialEq for UniformNotNan<T> |
2611 | | where |
2612 | | UniformFloat<T>: PartialEq, |
2613 | | { |
2614 | | fn eq(&self, other: &Self) -> bool { |
2615 | | self.0 == other.0 |
2616 | | } |
2617 | | } |
2618 | | |
2619 | | /// A sampler for a uniform distribution |
2620 | | #[derive(Clone, Copy, Debug)] |
2621 | | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
2622 | | pub struct UniformOrdered<T>(UniformFloat<T>); |
2623 | | impl SampleUniform for OrderedFloat<f32> { |
2624 | | type Sampler = UniformOrdered<f32>; |
2625 | | } |
2626 | | impl SampleUniform for OrderedFloat<f64> { |
2627 | | type Sampler = UniformOrdered<f64>; |
2628 | | } |
2629 | | impl<T> PartialEq for UniformOrdered<T> |
2630 | | where |
2631 | | UniformFloat<T>: PartialEq, |
2632 | | { |
2633 | | fn eq(&self, other: &Self) -> bool { |
2634 | | self.0 == other.0 |
2635 | | } |
2636 | | } |
2637 | | |
2638 | | macro_rules! impl_uniform_sampler { |
2639 | | ($f:ty) => { |
2640 | | impl UniformSampler for UniformNotNan<$f> { |
2641 | | type X = NotNan<$f>; |
2642 | | fn new<B1, B2>(low: B1, high: B2) -> Self |
2643 | | where |
2644 | | B1: SampleBorrow<Self::X> + Sized, |
2645 | | B2: SampleBorrow<Self::X> + Sized, |
2646 | | { |
2647 | | UniformNotNan(UniformFloat::<$f>::new(low.borrow().0, high.borrow().0)) |
2648 | | } |
2649 | | fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self |
2650 | | where |
2651 | | B1: SampleBorrow<Self::X> + Sized, |
2652 | | B2: SampleBorrow<Self::X> + Sized, |
2653 | | { |
2654 | | UniformSampler::new(low, high) |
2655 | | } |
2656 | | fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X { |
2657 | | // UniformFloat.sample() will never return NaN. |
2658 | | unsafe { NotNan::new_unchecked(self.0.sample(rng)) } |
2659 | | } |
2660 | | } |
2661 | | |
2662 | | impl UniformSampler for UniformOrdered<$f> { |
2663 | | type X = OrderedFloat<$f>; |
2664 | | fn new<B1, B2>(low: B1, high: B2) -> Self |
2665 | | where |
2666 | | B1: SampleBorrow<Self::X> + Sized, |
2667 | | B2: SampleBorrow<Self::X> + Sized, |
2668 | | { |
2669 | | UniformOrdered(UniformFloat::<$f>::new(low.borrow().0, high.borrow().0)) |
2670 | | } |
2671 | | fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self |
2672 | | where |
2673 | | B1: SampleBorrow<Self::X> + Sized, |
2674 | | B2: SampleBorrow<Self::X> + Sized, |
2675 | | { |
2676 | | UniformSampler::new(low, high) |
2677 | | } |
2678 | | fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X { |
2679 | | OrderedFloat(self.0.sample(rng)) |
2680 | | } |
2681 | | } |
2682 | | }; |
2683 | | } |
2684 | | |
2685 | | impl_uniform_sampler! { f32 } |
2686 | | impl_uniform_sampler! { f64 } |
2687 | | |
2688 | | #[cfg(all(test, feature = "randtest"))] |
2689 | | mod tests { |
2690 | | use super::*; |
2691 | | |
2692 | | fn sample_fuzz<T>() |
2693 | | where |
2694 | | Standard: Distribution<NotNan<T>>, |
2695 | | Open01: Distribution<NotNan<T>>, |
2696 | | OpenClosed01: Distribution<NotNan<T>>, |
2697 | | Standard: Distribution<OrderedFloat<T>>, |
2698 | | Open01: Distribution<OrderedFloat<T>>, |
2699 | | OpenClosed01: Distribution<OrderedFloat<T>>, |
2700 | | T: crate::Float, |
2701 | | { |
2702 | | let mut rng = rand::thread_rng(); |
2703 | | let f1: NotNan<T> = rng.sample(Standard); |
2704 | | let f2: NotNan<T> = rng.sample(Open01); |
2705 | | let f3: NotNan<T> = rng.sample(OpenClosed01); |
2706 | | let _: OrderedFloat<T> = rng.sample(Standard); |
2707 | | let _: OrderedFloat<T> = rng.sample(Open01); |
2708 | | let _: OrderedFloat<T> = rng.sample(OpenClosed01); |
2709 | | assert!(!f1.into_inner().is_nan()); |
2710 | | assert!(!f2.into_inner().is_nan()); |
2711 | | assert!(!f3.into_inner().is_nan()); |
2712 | | } |
2713 | | |
2714 | | #[test] |
2715 | | fn sampling_f32_does_not_panic() { |
2716 | | sample_fuzz::<f32>(); |
2717 | | } |
2718 | | |
2719 | | #[test] |
2720 | | fn sampling_f64_does_not_panic() { |
2721 | | sample_fuzz::<f64>(); |
2722 | | } |
2723 | | |
2724 | | #[test] |
2725 | | #[should_panic] |
2726 | | fn uniform_sampling_panic_on_infinity_notnan() { |
2727 | | let (low, high) = ( |
2728 | | NotNan::new(0f64).unwrap(), |
2729 | | NotNan::new(f64::INFINITY).unwrap(), |
2730 | | ); |
2731 | | let uniform = Uniform::new(low, high); |
2732 | | let _ = uniform.sample(&mut rand::thread_rng()); |
2733 | | } |
2734 | | |
2735 | | #[test] |
2736 | | #[should_panic] |
2737 | | fn uniform_sampling_panic_on_infinity_ordered() { |
2738 | | let (low, high) = (OrderedFloat(0f64), OrderedFloat(f64::INFINITY)); |
2739 | | let uniform = Uniform::new(low, high); |
2740 | | let _ = uniform.sample(&mut rand::thread_rng()); |
2741 | | } |
2742 | | |
2743 | | #[test] |
2744 | | #[should_panic] |
2745 | | fn uniform_sampling_panic_on_nan_ordered() { |
2746 | | let (low, high) = (OrderedFloat(0f64), OrderedFloat(f64::NAN)); |
2747 | | let uniform = Uniform::new(low, high); |
2748 | | let _ = uniform.sample(&mut rand::thread_rng()); |
2749 | | } |
2750 | | } |
2751 | | } |
2752 | | |
2753 | | #[cfg(feature = "proptest")] |
2754 | | mod impl_proptest { |
2755 | | use super::{NotNan, OrderedFloat}; |
2756 | | use proptest::arbitrary::{Arbitrary, StrategyFor}; |
2757 | | use proptest::num::{f32, f64}; |
2758 | | use proptest::strategy::{FilterMap, Map, Strategy}; |
2759 | | use std::convert::TryFrom; |
2760 | | |
2761 | | macro_rules! impl_arbitrary { |
2762 | | ($($f:ident),+) => { |
2763 | | $( |
2764 | | impl Arbitrary for NotNan<$f> { |
2765 | | type Strategy = FilterMap<StrategyFor<$f>, fn(_: $f) -> Option<NotNan<$f>>>; |
2766 | | type Parameters = <$f as Arbitrary>::Parameters; |
2767 | | fn arbitrary_with(params: Self::Parameters) -> Self::Strategy { |
2768 | | <$f>::arbitrary_with(params) |
2769 | | .prop_filter_map("filter nan values", |f| NotNan::try_from(f).ok()) |
2770 | | } |
2771 | | } |
2772 | | |
2773 | | impl Arbitrary for OrderedFloat<$f> { |
2774 | | type Strategy = Map<StrategyFor<$f>, fn(_: $f) -> OrderedFloat<$f>>; |
2775 | | type Parameters = <$f as Arbitrary>::Parameters; |
2776 | | fn arbitrary_with(params: Self::Parameters) -> Self::Strategy { |
2777 | | <$f>::arbitrary_with(params).prop_map(|f| OrderedFloat::from(f)) |
2778 | | } |
2779 | | } |
2780 | | )* |
2781 | | } |
2782 | | } |
2783 | | impl_arbitrary! { f32, f64 } |
2784 | | } |
2785 | | |
2786 | | #[cfg(feature = "arbitrary")] |
2787 | | mod impl_arbitrary { |
2788 | | use super::{FloatIsNan, NotNan, OrderedFloat}; |
2789 | | use arbitrary::{Arbitrary, Unstructured}; |
2790 | | use num_traits::FromPrimitive; |
2791 | | |
2792 | | macro_rules! impl_arbitrary { |
2793 | | ($($f:ident),+) => { |
2794 | | $( |
2795 | | impl<'a> Arbitrary<'a> for NotNan<$f> { |
2796 | 0 | fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> { |
2797 | 0 | let float: $f = u.arbitrary()?; |
2798 | 0 | match NotNan::new(float) { |
2799 | 0 | Ok(notnan_value) => Ok(notnan_value), |
2800 | | Err(FloatIsNan) => { |
2801 | | // If our arbitrary float input was a NaN (encoded by exponent = max |
2802 | | // value), then replace it with a finite float, reusing the mantissa |
2803 | | // bits. |
2804 | | // |
2805 | | // This means the output is not uniformly distributed among all |
2806 | | // possible float values, but Arbitrary makes no promise that that |
2807 | | // is true. |
2808 | | // |
2809 | | // An alternative implementation would be to return an |
2810 | | // `arbitrary::Error`, but that is not as useful since it forces the |
2811 | | // caller to retry with new random/fuzzed data; and the precendent of |
2812 | | // `arbitrary`'s built-in implementations is to prefer the approach of |
2813 | | // mangling the input bits to fit. |
2814 | | |
2815 | 0 | let (mantissa, _exponent, sign) = |
2816 | 0 | num_traits::float::FloatCore::integer_decode(float); |
2817 | 0 | let revised_float = <$f>::from_i64( |
2818 | 0 | i64::from(sign) * mantissa as i64 |
2819 | 0 | ).unwrap(); |
2820 | | |
2821 | | // If this unwrap() fails, then there is a bug in the above code. |
2822 | 0 | Ok(NotNan::new(revised_float).unwrap()) |
2823 | | } |
2824 | | } |
2825 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<f32> as arbitrary::Arbitrary>::arbitrary Unexecuted instantiation: <ordered_float::NotNan<f64> as arbitrary::Arbitrary>::arbitrary |
2826 | | |
2827 | 0 | fn size_hint(depth: usize) -> (usize, Option<usize>) { |
2828 | 0 | <$f as Arbitrary>::size_hint(depth) |
2829 | 0 | } Unexecuted instantiation: <ordered_float::NotNan<f32> as arbitrary::Arbitrary>::size_hint Unexecuted instantiation: <ordered_float::NotNan<f64> as arbitrary::Arbitrary>::size_hint |
2830 | | } |
2831 | | |
2832 | | impl<'a> Arbitrary<'a> for OrderedFloat<$f> { |
2833 | 0 | fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> { |
2834 | 0 | let float: $f = u.arbitrary()?; |
2835 | 0 | Ok(OrderedFloat::from(float)) |
2836 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as arbitrary::Arbitrary>::arbitrary Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as arbitrary::Arbitrary>::arbitrary |
2837 | | |
2838 | 0 | fn size_hint(depth: usize) -> (usize, Option<usize>) { |
2839 | 0 | <$f as Arbitrary>::size_hint(depth) |
2840 | 0 | } Unexecuted instantiation: <ordered_float::OrderedFloat<f64> as arbitrary::Arbitrary>::size_hint Unexecuted instantiation: <ordered_float::OrderedFloat<f32> as arbitrary::Arbitrary>::size_hint |
2841 | | } |
2842 | | )* |
2843 | | } |
2844 | | } |
2845 | | impl_arbitrary! { f32, f64 } |
2846 | | } |
2847 | | |
2848 | | #[cfg(feature = "bytemuck")] |
2849 | | mod impl_bytemuck { |
2850 | | use super::{FloatCore, NotNan, OrderedFloat}; |
2851 | | use bytemuck::{AnyBitPattern, CheckedBitPattern, NoUninit, Pod, TransparentWrapper, Zeroable}; |
2852 | | |
2853 | | unsafe impl<T: Zeroable> Zeroable for OrderedFloat<T> {} |
2854 | | |
2855 | | // The zero bit pattern is indeed not a NaN bit pattern. |
2856 | | unsafe impl<T: Zeroable> Zeroable for NotNan<T> {} |
2857 | | |
2858 | | unsafe impl<T: Pod> Pod for OrderedFloat<T> {} |
2859 | | |
2860 | | // `NotNan<T>` can only implement `NoUninit` and not `Pod`, since not every bit pattern is |
2861 | | // valid (NaN bit patterns are invalid). `NoUninit` guarantees that we can read any bit pattern |
2862 | | // from the value, which is fine in this case. |
2863 | | unsafe impl<T: NoUninit> NoUninit for NotNan<T> {} |
2864 | | |
2865 | | unsafe impl<T: FloatCore + AnyBitPattern> CheckedBitPattern for NotNan<T> { |
2866 | | type Bits = T; |
2867 | | |
2868 | | fn is_valid_bit_pattern(bits: &Self::Bits) -> bool { |
2869 | | !bits.is_nan() |
2870 | | } |
2871 | | } |
2872 | | |
2873 | | // OrderedFloat allows any value of the contained type, so it is a TransparentWrapper. |
2874 | | // NotNan does not, so it is not. |
2875 | | unsafe impl<T> TransparentWrapper<T> for OrderedFloat<T> {} |
2876 | | |
2877 | | #[test] |
2878 | | fn test_not_nan_bit_pattern() { |
2879 | | use bytemuck::checked::{try_cast, CheckedCastError}; |
2880 | | |
2881 | | let nan = f64::NAN; |
2882 | | assert_eq!( |
2883 | | try_cast::<f64, NotNan<f64>>(nan), |
2884 | | Err(CheckedCastError::InvalidBitPattern), |
2885 | | ); |
2886 | | |
2887 | | let pi = core::f64::consts::PI; |
2888 | | assert!(try_cast::<f64, NotNan<f64>>(pi).is_ok()); |
2889 | | } |
2890 | | } |