Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

185
vendor/approx/src/abs_diff_eq.rs vendored Normal file
View File

@@ -0,0 +1,185 @@
use core::cell;
#[cfg(feature = "num-complex")]
use num_complex::Complex;
/// Equality that is defined using the absolute difference of two numbers.
pub trait AbsDiffEq<Rhs = Self>: PartialEq<Rhs>
where
Rhs: ?Sized,
{
/// Used for specifying relative comparisons.
type Epsilon;
/// The default tolerance to use when testing values that are close together.
///
/// This is used when no `epsilon` value is supplied to the [`abs_diff_eq!`], [`relative_eq!`],
/// or [`ulps_eq!`] macros.
fn default_epsilon() -> Self::Epsilon;
/// A test for equality that uses the absolute difference to compute the approximate
/// equality of two numbers.
fn abs_diff_eq(&self, other: &Rhs, epsilon: Self::Epsilon) -> bool;
/// The inverse of [`AbsDiffEq::abs_diff_eq`].
fn abs_diff_ne(&self, other: &Rhs, epsilon: Self::Epsilon) -> bool {
!Self::abs_diff_eq(self, other, epsilon)
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Base implementations
///////////////////////////////////////////////////////////////////////////////////////////////////
macro_rules! impl_unsigned_abs_diff_eq {
($T:ident, $default_epsilon:expr) => {
impl AbsDiffEq for $T {
type Epsilon = $T;
#[inline]
fn default_epsilon() -> $T {
$default_epsilon
}
#[inline]
fn abs_diff_eq(&self, other: &$T, epsilon: $T) -> bool {
(if self > other {
self - other
} else {
other - self
}) <= epsilon
}
}
};
}
impl_unsigned_abs_diff_eq!(u8, 0);
impl_unsigned_abs_diff_eq!(u16, 0);
impl_unsigned_abs_diff_eq!(u32, 0);
impl_unsigned_abs_diff_eq!(u64, 0);
impl_unsigned_abs_diff_eq!(usize, 0);
macro_rules! impl_signed_abs_diff_eq {
($T:ident, $default_epsilon:expr) => {
impl AbsDiffEq for $T {
type Epsilon = $T;
#[inline]
fn default_epsilon() -> $T {
$default_epsilon
}
#[inline]
#[allow(unused_imports)]
fn abs_diff_eq(&self, other: &$T, epsilon: $T) -> bool {
use num_traits::float::FloatCore;
$T::abs(self - other) <= epsilon
}
}
};
}
impl_signed_abs_diff_eq!(i8, 0);
impl_signed_abs_diff_eq!(i16, 0);
impl_signed_abs_diff_eq!(i32, 0);
impl_signed_abs_diff_eq!(i64, 0);
impl_signed_abs_diff_eq!(isize, 0);
impl_signed_abs_diff_eq!(f32, core::f32::EPSILON);
impl_signed_abs_diff_eq!(f64, core::f64::EPSILON);
///////////////////////////////////////////////////////////////////////////////////////////////////
// Derived implementations
///////////////////////////////////////////////////////////////////////////////////////////////////
impl<'a, T: AbsDiffEq + ?Sized> AbsDiffEq for &'a T {
type Epsilon = T::Epsilon;
#[inline]
fn default_epsilon() -> T::Epsilon {
T::default_epsilon()
}
#[inline]
fn abs_diff_eq(&self, other: &&'a T, epsilon: T::Epsilon) -> bool {
T::abs_diff_eq(*self, *other, epsilon)
}
}
impl<'a, T: AbsDiffEq + ?Sized> AbsDiffEq for &'a mut T {
type Epsilon = T::Epsilon;
#[inline]
fn default_epsilon() -> T::Epsilon {
T::default_epsilon()
}
#[inline]
fn abs_diff_eq(&self, other: &&'a mut T, epsilon: T::Epsilon) -> bool {
T::abs_diff_eq(*self, *other, epsilon)
}
}
impl<T: AbsDiffEq + Copy> AbsDiffEq for cell::Cell<T> {
type Epsilon = T::Epsilon;
#[inline]
fn default_epsilon() -> T::Epsilon {
T::default_epsilon()
}
#[inline]
fn abs_diff_eq(&self, other: &cell::Cell<T>, epsilon: T::Epsilon) -> bool {
T::abs_diff_eq(&self.get(), &other.get(), epsilon)
}
}
impl<T: AbsDiffEq + ?Sized> AbsDiffEq for cell::RefCell<T> {
type Epsilon = T::Epsilon;
#[inline]
fn default_epsilon() -> T::Epsilon {
T::default_epsilon()
}
#[inline]
fn abs_diff_eq(&self, other: &cell::RefCell<T>, epsilon: T::Epsilon) -> bool {
T::abs_diff_eq(&self.borrow(), &other.borrow(), epsilon)
}
}
impl<A, B> AbsDiffEq<[B]> for [A]
where
A: AbsDiffEq<B>,
A::Epsilon: Clone,
{
type Epsilon = A::Epsilon;
#[inline]
fn default_epsilon() -> A::Epsilon {
A::default_epsilon()
}
#[inline]
fn abs_diff_eq(&self, other: &[B], epsilon: A::Epsilon) -> bool {
self.len() == other.len()
&& Iterator::zip(self.iter(), other).all(|(x, y)| A::abs_diff_eq(x, y, epsilon.clone()))
}
}
#[cfg(feature = "num-complex")]
impl<T: AbsDiffEq> AbsDiffEq for Complex<T>
where
T::Epsilon: Clone,
{
type Epsilon = T::Epsilon;
#[inline]
fn default_epsilon() -> T::Epsilon {
T::default_epsilon()
}
#[inline]
fn abs_diff_eq(&self, other: &Complex<T>, epsilon: T::Epsilon) -> bool {
T::abs_diff_eq(&self.re, &other.re, epsilon.clone())
&& T::abs_diff_eq(&self.im, &other.im, epsilon)
}
}

388
vendor/approx/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,388 @@
// Copyright 2015 Brendan Zabarauskas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! A crate that provides facilities for testing the approximate equality of floating-point
//! based types, using either relative difference, or units in the last place (ULPs)
//! comparisons.
//!
//! You can also use the `*_{eq, ne}!` and `assert_*_{eq, ne}!` macros to test for equality using a
//! more positional style:
//!
//! ```rust
//! #[macro_use]
//! extern crate approx;
//!
//! use std::f64;
//!
//! # fn main() {
//! abs_diff_eq!(1.0, 1.0);
//! abs_diff_eq!(1.0, 1.0, epsilon = f64::EPSILON);
//!
//! relative_eq!(1.0, 1.0);
//! relative_eq!(1.0, 1.0, epsilon = f64::EPSILON);
//! relative_eq!(1.0, 1.0, max_relative = 1.0);
//! relative_eq!(1.0, 1.0, epsilon = f64::EPSILON, max_relative = 1.0);
//! relative_eq!(1.0, 1.0, max_relative = 1.0, epsilon = f64::EPSILON);
//!
//! ulps_eq!(1.0, 1.0);
//! ulps_eq!(1.0, 1.0, epsilon = f64::EPSILON);
//! ulps_eq!(1.0, 1.0, max_ulps = 4);
//! ulps_eq!(1.0, 1.0, epsilon = f64::EPSILON, max_ulps = 4);
//! ulps_eq!(1.0, 1.0, max_ulps = 4, epsilon = f64::EPSILON);
//! # }
//! ```
//!
//! # Implementing approximate equality for custom types
//!
//! The `*Eq` traits allow approximate equalities to be implemented on types, based on the
//! fundamental floating point implementations.
//!
//! For example, we might want to be able to do approximate assertions on a complex number type:
//!
//! ```rust
//! #[macro_use]
//! extern crate approx;
//! # use approx::{AbsDiffEq, RelativeEq, UlpsEq};
//!
//! #[derive(Debug, PartialEq)]
//! struct Complex<T> {
//! x: T,
//! i: T,
//! }
//! # impl<T: AbsDiffEq> AbsDiffEq for Complex<T> where T::Epsilon: Copy {
//! # type Epsilon = T::Epsilon;
//! # fn default_epsilon() -> T::Epsilon { T::default_epsilon() }
//! # fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
//! # T::abs_diff_eq(&self.x, &other.x, epsilon) &&
//! # T::abs_diff_eq(&self.i, &other.i, epsilon)
//! # }
//! # }
//! # impl<T: RelativeEq> RelativeEq for Complex<T> where T::Epsilon: Copy {
//! # fn default_max_relative() -> T::Epsilon { T::default_max_relative() }
//! # fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon)
//! # -> bool {
//! # T::relative_eq(&self.x, &other.x, epsilon, max_relative) &&
//! # T::relative_eq(&self.i, &other.i, epsilon, max_relative)
//! # }
//! # }
//! # impl<T: UlpsEq> UlpsEq for Complex<T> where T::Epsilon: Copy {
//! # fn default_max_ulps() -> u32 { T::default_max_ulps() }
//! # fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
//! # T::ulps_eq(&self.x, &other.x, epsilon, max_ulps) &&
//! # T::ulps_eq(&self.i, &other.i, epsilon, max_ulps)
//! # }
//! # }
//!
//! # fn main() {
//! let x = Complex { x: 1.2, i: 2.3 };
//!
//! assert_relative_eq!(x, x);
//! assert_ulps_eq!(x, x, max_ulps = 4);
//! # }
//! ```
//!
//! To do this we can implement [`AbsDiffEq`], [`RelativeEq`] and [`UlpsEq`] generically in terms
//! of a type parameter that also implements `AbsDiffEq`, `RelativeEq` and `UlpsEq` respectively.
//! This means that we can make comparisons for either `Complex<f32>` or `Complex<f64>`:
//!
//! ```rust
//! # use approx::{AbsDiffEq, RelativeEq, UlpsEq};
//! # #[derive(Debug, PartialEq)]
//! # struct Complex<T> { x: T, i: T, }
//! #
//! impl<T: AbsDiffEq> AbsDiffEq for Complex<T> where
//! T::Epsilon: Copy,
//! {
//! type Epsilon = T::Epsilon;
//!
//! fn default_epsilon() -> T::Epsilon {
//! T::default_epsilon()
//! }
//!
//! fn abs_diff_eq(&self, other: &Self, epsilon: T::Epsilon) -> bool {
//! T::abs_diff_eq(&self.x, &other.x, epsilon) &&
//! T::abs_diff_eq(&self.i, &other.i, epsilon)
//! }
//! }
//!
//! impl<T: RelativeEq> RelativeEq for Complex<T> where
//! T::Epsilon: Copy,
//! {
//! fn default_max_relative() -> T::Epsilon {
//! T::default_max_relative()
//! }
//!
//! fn relative_eq(&self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
//! T::relative_eq(&self.x, &other.x, epsilon, max_relative) &&
//! T::relative_eq(&self.i, &other.i, epsilon, max_relative)
//! }
//! }
//!
//! impl<T: UlpsEq> UlpsEq for Complex<T> where
//! T::Epsilon: Copy,
//! {
//! fn default_max_ulps() -> u32 {
//! T::default_max_ulps()
//! }
//!
//! fn ulps_eq(&self, other: &Self, epsilon: T::Epsilon, max_ulps: u32) -> bool {
//! T::ulps_eq(&self.x, &other.x, epsilon, max_ulps) &&
//! T::ulps_eq(&self.i, &other.i, epsilon, max_ulps)
//! }
//! }
//! ```
//!
//! # References
//!
//! Floating point is hard! Thanks goes to these links for helping to make things a _little_
//! easier to understand:
//!
//! - [Comparing Floating Point Numbers, 2012 Edition](
//! https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/)
//! - [The Floating Point Guide - Comparison](http://floating-point-gui.de/errors/comparison/)
//! - [What Every Computer Scientist Should Know About Floating-Point Arithmetic](
//! https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)
#![no_std]
#![allow(clippy::transmute_float_to_int)]
#[cfg(feature = "num-complex")]
extern crate num_complex;
extern crate num_traits;
mod abs_diff_eq;
mod relative_eq;
mod ulps_eq;
mod macros;
pub use abs_diff_eq::AbsDiffEq;
pub use relative_eq::RelativeEq;
pub use ulps_eq::UlpsEq;
/// The requisite parameters for testing for approximate equality using a
/// absolute difference based comparison.
///
/// This is not normally used directly, rather via the
/// `assert_abs_diff_{eq|ne}!` and `abs_diff_{eq|ne}!` macros.
///
/// # Example
///
/// ```rust
/// use std::f64;
/// use approx::AbsDiff;
///
/// AbsDiff::default().eq(&1.0, &1.0);
/// AbsDiff::default().epsilon(f64::EPSILON).eq(&1.0, &1.0);
/// ```
pub struct AbsDiff<A, B = A>
where
A: AbsDiffEq<B> + ?Sized,
B: ?Sized,
{
/// The tolerance to use when testing values that are close together.
pub epsilon: A::Epsilon,
}
impl<A, B> Default for AbsDiff<A, B>
where
A: AbsDiffEq<B> + ?Sized,
B: ?Sized,
{
#[inline]
fn default() -> AbsDiff<A, B> {
AbsDiff {
epsilon: A::default_epsilon(),
}
}
}
impl<A, B> AbsDiff<A, B>
where
A: AbsDiffEq<B> + ?Sized,
B: ?Sized,
{
/// Replace the epsilon value with the one specified.
#[inline]
pub fn epsilon(self, epsilon: A::Epsilon) -> AbsDiff<A, B> {
AbsDiff { epsilon }
}
/// Peform the equality comparison
#[inline]
#[must_use]
pub fn eq(self, lhs: &A, rhs: &B) -> bool {
A::abs_diff_eq(lhs, rhs, self.epsilon)
}
/// Peform the inequality comparison
#[inline]
#[must_use]
pub fn ne(self, lhs: &A, rhs: &B) -> bool {
A::abs_diff_ne(lhs, rhs, self.epsilon)
}
}
/// The requisite parameters for testing for approximate equality using a
/// relative based comparison.
///
/// This is not normally used directly, rather via the
/// `assert_relative_{eq|ne}!` and `relative_{eq|ne}!` macros.
///
/// # Example
///
/// ```rust
/// use std::f64;
/// use approx::Relative;
///
/// Relative::default().eq(&1.0, &1.0);
/// Relative::default().epsilon(f64::EPSILON).eq(&1.0, &1.0);
/// Relative::default().max_relative(1.0).eq(&1.0, &1.0);
/// Relative::default().epsilon(f64::EPSILON).max_relative(1.0).eq(&1.0, &1.0);
/// Relative::default().max_relative(1.0).epsilon(f64::EPSILON).eq(&1.0, &1.0);
/// ```
pub struct Relative<A, B = A>
where
A: RelativeEq<B> + ?Sized,
B: ?Sized,
{
/// The tolerance to use when testing values that are close together.
pub epsilon: A::Epsilon,
/// The relative tolerance for testing values that are far-apart.
pub max_relative: A::Epsilon,
}
impl<A, B> Default for Relative<A, B>
where
A: RelativeEq<B> + ?Sized,
B: ?Sized,
{
#[inline]
fn default() -> Relative<A, B> {
Relative {
epsilon: A::default_epsilon(),
max_relative: A::default_max_relative(),
}
}
}
impl<A, B> Relative<A, B>
where
A: RelativeEq<B> + ?Sized,
B: ?Sized,
{
/// Replace the epsilon value with the one specified.
#[inline]
pub fn epsilon(self, epsilon: A::Epsilon) -> Relative<A, B> {
Relative { epsilon, ..self }
}
/// Replace the maximum relative value with the one specified.
#[inline]
pub fn max_relative(self, max_relative: A::Epsilon) -> Relative<A, B> {
Relative {
max_relative,
..self
}
}
/// Peform the equality comparison
#[inline]
#[must_use]
pub fn eq(self, lhs: &A, rhs: &B) -> bool {
A::relative_eq(lhs, rhs, self.epsilon, self.max_relative)
}
/// Peform the inequality comparison
#[inline]
#[must_use]
pub fn ne(self, lhs: &A, rhs: &B) -> bool {
A::relative_ne(lhs, rhs, self.epsilon, self.max_relative)
}
}
/// The requisite parameters for testing for approximate equality using an ULPs
/// based comparison.
///
/// This is not normally used directly, rather via the `assert_ulps_{eq|ne}!`
/// and `ulps_{eq|ne}!` macros.
///
/// # Example
///
/// ```rust
/// use std::f64;
/// use approx::Ulps;
///
/// Ulps::default().eq(&1.0, &1.0);
/// Ulps::default().epsilon(f64::EPSILON).eq(&1.0, &1.0);
/// Ulps::default().max_ulps(4).eq(&1.0, &1.0);
/// Ulps::default().epsilon(f64::EPSILON).max_ulps(4).eq(&1.0, &1.0);
/// Ulps::default().max_ulps(4).epsilon(f64::EPSILON).eq(&1.0, &1.0);
/// ```
pub struct Ulps<A, B = A>
where
A: UlpsEq<B> + ?Sized,
B: ?Sized,
{
/// The tolerance to use when testing values that are close together.
pub epsilon: A::Epsilon,
/// The ULPs to tolerate when testing values that are far-apart.
pub max_ulps: u32,
}
impl<A, B> Default for Ulps<A, B>
where
A: UlpsEq<B> + ?Sized,
B: ?Sized,
{
#[inline]
fn default() -> Ulps<A, B> {
Ulps {
epsilon: A::default_epsilon(),
max_ulps: A::default_max_ulps(),
}
}
}
impl<A, B> Ulps<A, B>
where
A: UlpsEq<B> + ?Sized,
B: ?Sized,
{
/// Replace the epsilon value with the one specified.
#[inline]
pub fn epsilon(self, epsilon: A::Epsilon) -> Ulps<A, B> {
Ulps { epsilon, ..self }
}
/// Replace the max ulps value with the one specified.
#[inline]
pub fn max_ulps(self, max_ulps: u32) -> Ulps<A, B> {
Ulps { max_ulps, ..self }
}
/// Peform the equality comparison
#[inline]
#[must_use]
pub fn eq(self, lhs: &A, rhs: &B) -> bool {
A::ulps_eq(lhs, rhs, self.epsilon, self.max_ulps)
}
/// Peform the inequality comparison
#[inline]
#[must_use]
pub fn ne(self, lhs: &A, rhs: &B) -> bool {
A::ulps_ne(lhs, rhs, self.epsilon, self.max_ulps)
}
}

185
vendor/approx/src/macros.rs vendored Normal file
View File

@@ -0,0 +1,185 @@
// Copyright 2015 Brendan Zabarauskas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// Approximate equality of using the absolute difference.
#[macro_export]
macro_rules! abs_diff_eq {
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
$crate::AbsDiff::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
};
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
$crate::AbsDiff::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
};
}
/// Approximate inequality of using the absolute difference.
#[macro_export]
macro_rules! abs_diff_ne {
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
$crate::AbsDiff::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
};
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
$crate::AbsDiff::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
};
}
/// Approximate equality using both the absolute difference and relative based comparisons.
#[macro_export]
macro_rules! relative_eq {
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
$crate::Relative::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
};
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
$crate::Relative::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
};
}
/// Approximate inequality using both the absolute difference and relative based comparisons.
#[macro_export]
macro_rules! relative_ne {
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
$crate::Relative::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
};
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
$crate::Relative::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
};
}
/// Approximate equality using both the absolute difference and ULPs (Units in Last Place).
#[macro_export]
macro_rules! ulps_eq {
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
$crate::Ulps::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
};
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
$crate::Ulps::default()$(.$opt($val))*.eq(&$lhs, &$rhs)
};
}
/// Approximate inequality using both the absolute difference and ULPs (Units in Last Place).
#[macro_export]
macro_rules! ulps_ne {
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*) => {
$crate::Ulps::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
};
($lhs:expr, $rhs:expr $(, $opt:ident = $val:expr)*,) => {
$crate::Ulps::default()$(.$opt($val))*.ne(&$lhs, &$rhs)
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __assert_approx {
($eq:ident, $given:expr, $expected:expr) => {{
match (&($given), &($expected)) {
(given, expected) => assert!(
$eq!(*given, *expected),
"assert_{}!({}, {})
left = {:?}
right = {:?}
",
stringify!($eq),
stringify!($given),
stringify!($expected),
given, expected,
),
}
}};
($eq:ident, $given:expr, $expected:expr, $($opt:ident = $val:expr),+) => {{
match (&($given), &($expected)) {
(given, expected) => assert!(
$eq!(*given, *expected, $($opt = $val),+),
"assert_{}!({}, {}, {})
left = {:?}
right = {:?}
",
stringify!($eq),
stringify!($given),
stringify!($expected),
stringify!($($opt = $val),+),
given, expected,
),
}
}};
}
/// An assertion that delegates to [`abs_diff_eq!`], and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_abs_diff_eq {
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
__assert_approx!(abs_diff_eq, $given, $expected $(, $opt = $val)*)
};
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
__assert_approx!(abs_diff_eq, $given, $expected $(, $opt = $val)*)
};
}
/// An assertion that delegates to [`abs_diff_ne!`], and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_abs_diff_ne {
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
__assert_approx!(abs_diff_ne, $given, $expected $(, $opt = $val)*)
};
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
__assert_approx!(abs_diff_ne, $given, $expected $(, $opt = $val)*)
};
}
/// An assertion that delegates to [`relative_eq!`], and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_relative_eq {
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
__assert_approx!(relative_eq, $given, $expected $(, $opt = $val)*)
};
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
__assert_approx!(relative_eq, $given, $expected $(, $opt = $val)*)
};
}
/// An assertion that delegates to [`relative_ne!`], and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_relative_ne {
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
__assert_approx!(relative_ne, $given, $expected $(, $opt = $val)*)
};
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
__assert_approx!(relative_ne, $given, $expected $(, $opt = $val)*)
};
}
/// An assertion that delegates to [`ulps_eq!`], and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_ulps_eq {
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
__assert_approx!(ulps_eq, $given, $expected $(, $opt = $val)*)
};
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
__assert_approx!(ulps_eq, $given, $expected $(, $opt = $val)*)
};
}
/// An assertion that delegates to [`ulps_ne!`], and panics with a helpful error on failure.
#[macro_export(local_inner_macros)]
macro_rules! assert_ulps_ne {
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*) => {
__assert_approx!(ulps_ne, $given, $expected $(, $opt = $val)*)
};
($given:expr, $expected:expr $(, $opt:ident = $val:expr)*,) => {
__assert_approx!(ulps_ne, $given, $expected $(, $opt = $val)*)
};
}

191
vendor/approx/src/relative_eq.rs vendored Normal file
View File

@@ -0,0 +1,191 @@
use core::{cell, f32, f64};
#[cfg(feature = "num-complex")]
use num_complex::Complex;
use AbsDiffEq;
/// Equality comparisons between two numbers using both the absolute difference and
/// relative based comparisons.
pub trait RelativeEq<Rhs = Self>: AbsDiffEq<Rhs>
where
Rhs: ?Sized,
{
/// The default relative tolerance for testing values that are far-apart.
///
/// This is used when no `max_relative` value is supplied to the [`relative_eq`] macro.
fn default_max_relative() -> Self::Epsilon;
/// A test for equality that uses a relative comparison if the values are far apart.
fn relative_eq(&self, other: &Rhs, epsilon: Self::Epsilon, max_relative: Self::Epsilon)
-> bool;
/// The inverse of [`RelativeEq::relative_eq`].
fn relative_ne(
&self,
other: &Rhs,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon,
) -> bool {
!Self::relative_eq(self, other, epsilon, max_relative)
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Base implementations
///////////////////////////////////////////////////////////////////////////////////////////////////
// Implementation based on: [Comparing Floating Point Numbers, 2012 Edition]
// (https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/)
macro_rules! impl_relative_eq {
($T:ident, $U:ident) => {
impl RelativeEq for $T {
#[inline]
fn default_max_relative() -> $T {
$T::EPSILON
}
#[inline]
#[allow(unused_imports)]
fn relative_eq(&self, other: &$T, epsilon: $T, max_relative: $T) -> bool {
use num_traits::float::FloatCore;
// Handle same infinities
if self == other {
return true;
}
// Handle remaining infinities
if $T::is_infinite(*self) || $T::is_infinite(*other) {
return false;
}
let abs_diff = $T::abs(self - other);
// For when the numbers are really close together
if abs_diff <= epsilon {
return true;
}
let abs_self = $T::abs(*self);
let abs_other = $T::abs(*other);
let largest = if abs_other > abs_self {
abs_other
} else {
abs_self
};
// Use a relative difference comparison
abs_diff <= largest * max_relative
}
}
};
}
impl_relative_eq!(f32, i32);
impl_relative_eq!(f64, i64);
///////////////////////////////////////////////////////////////////////////////////////////////////
// Derived implementations
///////////////////////////////////////////////////////////////////////////////////////////////////
impl<'a, T: RelativeEq + ?Sized> RelativeEq for &'a T {
#[inline]
fn default_max_relative() -> T::Epsilon {
T::default_max_relative()
}
#[inline]
fn relative_eq(&self, other: &&'a T, epsilon: T::Epsilon, max_relative: T::Epsilon) -> bool {
T::relative_eq(*self, *other, epsilon, max_relative)
}
}
impl<'a, T: RelativeEq + ?Sized> RelativeEq for &'a mut T {
#[inline]
fn default_max_relative() -> T::Epsilon {
T::default_max_relative()
}
#[inline]
fn relative_eq(
&self,
other: &&'a mut T,
epsilon: T::Epsilon,
max_relative: T::Epsilon,
) -> bool {
T::relative_eq(*self, *other, epsilon, max_relative)
}
}
impl<T: RelativeEq + Copy> RelativeEq for cell::Cell<T> {
#[inline]
fn default_max_relative() -> T::Epsilon {
T::default_max_relative()
}
#[inline]
fn relative_eq(
&self,
other: &cell::Cell<T>,
epsilon: T::Epsilon,
max_relative: T::Epsilon,
) -> bool {
T::relative_eq(&self.get(), &other.get(), epsilon, max_relative)
}
}
impl<T: RelativeEq + ?Sized> RelativeEq for cell::RefCell<T> {
#[inline]
fn default_max_relative() -> T::Epsilon {
T::default_max_relative()
}
#[inline]
fn relative_eq(
&self,
other: &cell::RefCell<T>,
epsilon: T::Epsilon,
max_relative: T::Epsilon,
) -> bool {
T::relative_eq(&self.borrow(), &other.borrow(), epsilon, max_relative)
}
}
impl<A, B> RelativeEq<[B]> for [A]
where
A: RelativeEq<B>,
A::Epsilon: Clone,
{
#[inline]
fn default_max_relative() -> A::Epsilon {
A::default_max_relative()
}
#[inline]
fn relative_eq(&self, other: &[B], epsilon: A::Epsilon, max_relative: A::Epsilon) -> bool {
self.len() == other.len()
&& Iterator::zip(self.iter(), other)
.all(|(x, y)| A::relative_eq(x, y, epsilon.clone(), max_relative.clone()))
}
}
#[cfg(feature = "num-complex")]
impl<T: RelativeEq> RelativeEq for Complex<T>
where
T::Epsilon: Clone,
{
#[inline]
fn default_max_relative() -> T::Epsilon {
T::default_max_relative()
}
#[inline]
fn relative_eq(
&self,
other: &Complex<T>,
epsilon: T::Epsilon,
max_relative: T::Epsilon,
) -> bool {
T::relative_eq(&self.re, &other.re, epsilon.clone(), max_relative.clone())
&& T::relative_eq(&self.im, &other.im, epsilon, max_relative)
}
}

158
vendor/approx/src/ulps_eq.rs vendored Normal file
View File

@@ -0,0 +1,158 @@
use core::cell;
#[cfg(feature = "num-complex")]
use num_complex::Complex;
use num_traits::Signed;
use AbsDiffEq;
/// Equality comparisons between two numbers using both the absolute difference and ULPs
/// (Units in Last Place) based comparisons.
pub trait UlpsEq<Rhs = Self>: AbsDiffEq<Rhs>
where
Rhs: ?Sized,
{
/// The default ULPs to tolerate when testing values that are far-apart.
///
/// This is used when no `max_ulps` value is supplied to the [`ulps_eq`] macro.
fn default_max_ulps() -> u32;
/// A test for equality that uses units in the last place (ULP) if the values are far apart.
fn ulps_eq(&self, other: &Rhs, epsilon: Self::Epsilon, max_ulps: u32) -> bool;
/// The inverse of [`UlpsEq::ulps_eq`].
fn ulps_ne(&self, other: &Rhs, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
!Self::ulps_eq(self, other, epsilon, max_ulps)
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Base implementations
///////////////////////////////////////////////////////////////////////////////////////////////////
// Implementation based on: [Comparing Floating Point Numbers, 2012 Edition]
// (https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/)
macro_rules! impl_ulps_eq {
($T:ident, $U:ident) => {
impl UlpsEq for $T {
#[inline]
fn default_max_ulps() -> u32 {
4
}
#[inline]
fn ulps_eq(&self, other: &$T, epsilon: $T, max_ulps: u32) -> bool {
// For when the numbers are really close together
if $T::abs_diff_eq(self, other, epsilon) {
return true;
}
// Trivial negative sign check
if self.signum() != other.signum() {
return false;
}
// ULPS difference comparison
let int_self: $U = self.to_bits();
let int_other: $U = other.to_bits();
// To be replaced with `abs_sub`, if
// https://github.com/rust-lang/rust/issues/62111 lands.
if int_self <= int_other {
int_other - int_self <= max_ulps as $U
} else {
int_self - int_other <= max_ulps as $U
}
}
}
};
}
impl_ulps_eq!(f32, u32);
impl_ulps_eq!(f64, u64);
///////////////////////////////////////////////////////////////////////////////////////////////////
// Derived implementations
///////////////////////////////////////////////////////////////////////////////////////////////////
impl<'a, T: UlpsEq + ?Sized> UlpsEq for &'a T {
#[inline]
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
#[inline]
fn ulps_eq(&self, other: &&'a T, epsilon: T::Epsilon, max_ulps: u32) -> bool {
T::ulps_eq(*self, *other, epsilon, max_ulps)
}
}
impl<'a, T: UlpsEq + ?Sized> UlpsEq for &'a mut T {
#[inline]
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
#[inline]
fn ulps_eq(&self, other: &&'a mut T, epsilon: T::Epsilon, max_ulps: u32) -> bool {
T::ulps_eq(*self, *other, epsilon, max_ulps)
}
}
impl<T: UlpsEq + Copy> UlpsEq for cell::Cell<T> {
#[inline]
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
#[inline]
fn ulps_eq(&self, other: &cell::Cell<T>, epsilon: T::Epsilon, max_ulps: u32) -> bool {
T::ulps_eq(&self.get(), &other.get(), epsilon, max_ulps)
}
}
impl<T: UlpsEq + ?Sized> UlpsEq for cell::RefCell<T> {
#[inline]
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
#[inline]
fn ulps_eq(&self, other: &cell::RefCell<T>, epsilon: T::Epsilon, max_ulps: u32) -> bool {
T::ulps_eq(&self.borrow(), &other.borrow(), epsilon, max_ulps)
}
}
impl<A, B> UlpsEq<[B]> for [A]
where
A: UlpsEq<B>,
A::Epsilon: Clone,
{
#[inline]
fn default_max_ulps() -> u32 {
A::default_max_ulps()
}
#[inline]
fn ulps_eq(&self, other: &[B], epsilon: A::Epsilon, max_ulps: u32) -> bool {
self.len() == other.len()
&& Iterator::zip(self.iter(), other)
.all(|(x, y)| A::ulps_eq(x, y, epsilon.clone(), max_ulps))
}
}
#[cfg(feature = "num-complex")]
impl<T: UlpsEq> UlpsEq for Complex<T>
where
T::Epsilon: Clone,
{
#[inline]
fn default_max_ulps() -> u32 {
T::default_max_ulps()
}
#[inline]
fn ulps_eq(&self, other: &Complex<T>, epsilon: T::Epsilon, max_ulps: u32) -> bool {
T::ulps_eq(&self.re, &other.re, epsilon.clone(), max_ulps)
&& T::ulps_eq(&self.im, &other.im, epsilon, max_ulps)
}
}