pub struct Finite<T: FiniteFloat>(/* private fields */);Expand description
Experimental: A transparent wrapper around f64 and friends with total ordering.
Comparison, equality, and hashing all agree with total_cmp after zero normalization.
§Basic Usage
use range_set_blaze::{RangeSetBlaze, FiniteF64, FiniteF32};
let set = RangeSetBlaze::from_iter([FiniteF64::new(3.0)..=FiniteF64::new(5.0)]);
assert!(set.contains(FiniteF64::new(3.1)));
assert!(!set.contains(FiniteF64::new(2.9)));
let set = RangeSetBlaze::from(FiniteF64::from_primitive_range(3.0..=5.0));
assert!(set.contains(FiniteF64::new(4.9)));
assert!(!set.contains(FiniteF64::new(5.1)));
let set = RangeSetBlaze::from_iter(FiniteF32::from_primitive_ranges([3.0..=5.0, 7.0..=9.0]));
assert!(set.contains(FiniteF32::new(4.0)));
assert!(!set.contains(FiniteF32::new(6.0)));§Enabling
This type is experimental and must be enabled with the float_experimental feature.
cargo add range-set-blaze --features "float_experimental"That provides the FiniteF32 and FiniteF64 types.
If you’re building with nightly, you can instead use the float_nightly_experimental feature.
cargo add range-set-blaze --features "float_nightly_experimental"To also use the FiniteF16 and FiniteF128 types.
Implementations§
Source§impl<T: FiniteFloat> Finite<T>
impl<T: FiniteFloat> Finite<T>
Sourcepub const MIN: Self
pub const MIN: Self
The minimum value that can be represented by the type.
Maps directly to crate::Integer::min_value()
§Examples
use range_set_blaze::FiniteF64;
assert_eq!(FiniteF64::MIN, FiniteF64::new(f64::MIN));Sourcepub const MAX: Self
pub const MAX: Self
The maximum value that can be represented by the type.
Maps directly to crate::Integer::max_value()
§Examples
use range_set_blaze::FiniteF64;
assert_eq!(FiniteF64::MAX, FiniteF64::new(f64::MAX));Sourcepub const MAX_SIZE: T::SafeLen = T::MAX_SIZE
pub const MAX_SIZE: T::SafeLen = T::MAX_SIZE
The maximum possible size of a range, i.e. the size if [MIN..=MAX]
For Finite types, this is unusual because NaN and infinity values are excluded, and
-0.0 and +0.0 share one slot after normalization.
§Examples
use range_set_blaze::FiniteF32;
assert_eq!(FiniteF32::MAX_SIZE, 0xFF00_0000_u32 - 1);Sourcepub const unsafe fn new_unchecked(x: T) -> Self
pub const unsafe fn new_unchecked(x: T) -> Self
Creates a new Finite from a primitive float without validating it.
This is the unchecked building block every validating constructor in this module
(new, try_new, from_primitive_range, values,
from_primitive_slice, …) is defined in terms
of. Prefer those; only reach for this when you have already independently established
the safety precondition below and need to skip the redundant check.
§Safety
The caller must guarantee that:
xis finite: not NaN, not+/-infinity.xis not-0.0: zero must already be canonicalized to+0.0.
Finite has a public type invariant (“only finite values, with zero canonicalized to
+0.0, are legal”). Even though today’s implementation would only produce incorrect
results (wrong MAX_SIZE, a duplicated zero slot, after/before landing somewhere
unexpected) rather than immediate undefined behavior if this precondition is violated,
safe code must never be able to construct a value that breaks it. This preserves the
option for this crate, and downstream code, to rely on the invariant in future
(potentially unsafe) abstractions without an audit of every safe caller.
Sourcepub fn inclusive_end_from_start(self, b: T::SafeLen) -> Self
pub fn inclusive_end_from_start(self, b: T::SafeLen) -> Self
Computes self + (b - 1) where b is of type SafeLen.
§Panics
Panics if b is not small enough that the result stays within range for T
(checked unconditionally, in both debug and release builds, so safe code can
never construct a Finite value that breaks its invariant this way).
Sourcepub fn start_from_inclusive_end(self, b: T::SafeLen) -> Self
pub fn start_from_inclusive_end(self, b: T::SafeLen) -> Self
Computes self - (b - 1) where b is of type SafeLen.
§Panics
Panics if b is not small enough that the result stays within range for T
(checked unconditionally, in both debug and release builds, so safe code can
never construct a Finite value that breaks its invariant this way).
Sourcepub const fn into_inner(self) -> T
pub const fn into_inner(self) -> T
Returns the wrapped value.
§Examples
use range_set_blaze::FiniteF64;
assert_eq!(FiniteF64::new(42.0).into_inner(), 42.0);Sourcepub fn after(self) -> Self
pub fn after(self) -> Self
Returns the next float, in total order.
§Examples
use range_set_blaze::FiniteF64;
assert_eq!(FiniteF64::new(42.0).after().before().into_inner(), 42.0);§Panics
Panics if self is the maximum value (checked unconditionally, in both debug
and release builds, so safe code can never construct a Finite value that
breaks its invariant this way).
Sourcepub fn before(self) -> Self
pub fn before(self) -> Self
Returns the previous float, in total order.
§Examples
use range_set_blaze::FiniteF64;
assert_eq!(FiniteF64::new(42.0).before().after().into_inner(), 42.0);§Panics
Panics if self is the minimum value (checked unconditionally, in both debug
and release builds, so safe code can never construct a Finite value that
breaks its invariant this way).
Sourcepub fn checked_after(self) -> Option<Self>
pub fn checked_after(self) -> Option<Self>
Sourcepub fn checked_before(self) -> Option<Self>
pub fn checked_before(self) -> Option<Self>
Sourcepub fn from_primitive_range(range: RangeInclusive<T>) -> RangeInclusive<Self>
pub fn from_primitive_range(range: RangeInclusive<T>) -> RangeInclusive<Self>
Converts an inclusive primitive range into an inclusive Finite range.
“Primitive” here means Rust’s built-in float type (e.g. f64).
§Examples
use range_set_blaze::{RangeSetBlaze, FiniteF64};
let short = RangeSetBlaze::from(FiniteF64::from_primitive_range(3.0..=5.0));
let long = RangeSetBlaze::from(FiniteF64::new(3.0)..=FiniteF64::new(5.0));
assert_eq!(short, long);§Panics
Panics if start or end is not finite.
Sourcepub fn from_primitive_ranges<I>(
ranges: I,
) -> impl Iterator<Item = RangeInclusive<Self>>where
I: IntoIterator<Item = RangeInclusive<T>>,
pub fn from_primitive_ranges<I>(
ranges: I,
) -> impl Iterator<Item = RangeInclusive<Self>>where
I: IntoIterator<Item = RangeInclusive<T>>,
Converts inclusive primitive ranges into inclusive Finite ranges.
“Primitive” here means Rust’s built-in float type (e.g. f64).
§Examples
use range_set_blaze::{RangeSetBlaze, FiniteF64};
let short = RangeSetBlaze::from_iter(FiniteF64::from_primitive_ranges([1.0..=2.0, 3.0..=4.0]));
let long = RangeSetBlaze::from_iter([FiniteF64::new(1.0)..=FiniteF64::new(2.0), FiniteF64::new(3.0)..=FiniteF64::new(4.0)]);
assert_eq!(short, long);§Panics
Panics when the returned iterator is consumed if any range endpoint is not finite.
Sourcepub fn values<I>(values: I) -> impl Iterator<Item = Self>where
I: IntoIterator<Item = T>,
pub fn values<I>(values: I) -> impl Iterator<Item = Self>where
I: IntoIterator<Item = T>,
Convenience method to convert primitive values into ordered Finite values.
§Examples
use range_set_blaze::{RangeSetBlaze, FiniteF64};
let short = RangeSetBlaze::from_iter(FiniteF64::values([1.0, 2.0, 3.0, 4.0]));
let long = RangeSetBlaze::from_iter([FiniteF64::new(1.0), FiniteF64::new(2.0), FiniteF64::new(3.0), FiniteF64::new(4.0)]);
assert_eq!(short, long);§Panics
Panics (when iterated) if any value is not finite.
Sourcepub fn from_primitive_slice(values: &[T]) -> &[Self]
pub fn from_primitive_slice(values: &[T]) -> &[Self]
Views primitive values as ordered Finite values, validating as it goes.
“Primitive” here means Rust’s built-in float type (e.g. f64).
This runs in O(n) (to validate every element) and does not allocate.
§Examples
use range_set_blaze::{RangeSetBlaze, FiniteF64};
let short = RangeSetBlaze::from_iter(FiniteF64::from_primitive_slice(&[1.0, 2.0, 3.0, 4.0]));
let long = RangeSetBlaze::from_iter([FiniteF64::new(1.0), FiniteF64::new(2.0), FiniteF64::new(3.0), FiniteF64::new(4.0)]);
assert_eq!(short, long);§Panics
Panics if any element is not finite, or is -0.0 (which can’t be normalized to +0.0
without copying — see Finite::from_primitive_slice_unchecked if you need a true
zero-copy view and can guarantee your data already satisfies Finite’s invariant).
Sourcepub const unsafe fn from_primitive_slice_unchecked(values: &[T]) -> &[Self]
pub const unsafe fn from_primitive_slice_unchecked(values: &[T]) -> &[Self]
Views primitive values as ordered Finite values, without validating them.
“Primitive” here means Rust’s built-in float type (e.g. f64).
This runs in O(1) and does not allocate.
§Safety
The caller must guarantee that every element of values is finite (not NaN, not
+/-infinity) and not -0.0 (zero must already be canonicalized to +0.0). Because
the returned slice is a live view over the same memory (not a copy), there is no
opportunity to normalize -0.0 even if the caller wanted to; the data must already be
clean.
Finite has a public type invariant that safe code must never be able to break, even
though violating it today would only produce incorrect results (see
Finite::new_unchecked for the full rationale).
Trait Implementations§
impl<T: Copy + FiniteFloat> Copy for Finite<T>
impl<T: FiniteFloat> Eq for Finite<T>
Source§impl<T: FiniteFloat> Integer for Finite<T>
impl<T: FiniteFloat> Integer for Finite<T>
Source§type SafeLen = <T as FiniteFloat>::SafeLen
type SafeLen = <T as FiniteFloat>::SafeLen
RangeSetBlaze. For example, the length of a RangeSetBlaze<u8> is u16 to handle ranges up to 256 elements.
For larger types like u128, this is represented by a custom type UIntPlusOne<u128>. Read moreSource§fn checked_add_one(self) -> Option<Self>
fn checked_add_one(self) -> Option<Self>
None if the operation would overflow.Source§fn add_one(self) -> Self
fn add_one(self) -> Self
Source§fn sub_one(self) -> Self
fn sub_one(self) -> Self
Source§fn assign_sub_one(&mut self)
fn assign_sub_one(&mut self)
self.Source§fn range_next(range: &mut RangeInclusive<Self>) -> Option<Self>
fn range_next(range: &mut RangeInclusive<Self>) -> Option<Self>
None if the range is exhausted. Read moreSource§fn range_next_back(range: &mut RangeInclusive<Self>) -> Option<Self>
fn range_next_back(range: &mut RangeInclusive<Self>) -> Option<Self>
None if the range is exhausted. Read moreSource§fn min_value() -> Self
fn min_value() -> Self
Source§fn max_value() -> Self
fn max_value() -> Self
Source§fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self>
fn from_slice(slice: impl AsRef<[Self]>) -> RangeSetBlaze<Self>
RangeSetBlaze from a slice, specific to the integer type.Source§fn safe_len(r: &RangeInclusive<Self>) -> Self::SafeLen
fn safe_len(r: &RangeInclusive<Self>) -> Self::SafeLen
Source§fn safe_len_to_f64_lossy(len: Self::SafeLen) -> f64
fn safe_len_to_f64_lossy(len: Self::SafeLen) -> f64
Integer::SafeLen to f64, potentially losing precision for large values.Source§fn f64_to_safe_len_lossy(f: f64) -> Self::SafeLen
fn f64_to_safe_len_lossy(f: f64) -> Self::SafeLen
f64 to Integer::SafeLen using the formula f as Self::SafeLen. For large integer types, this will result in a loss of precision.Source§fn inclusive_end_from_start(self, b: Self::SafeLen) -> Self
fn inclusive_end_from_start(self, b: Self::SafeLen) -> Self
Source§fn start_from_inclusive_end(self, b: Self::SafeLen) -> Self
fn start_from_inclusive_end(self, b: Self::SafeLen) -> Self
Source§fn exhausted_range() -> RangeInclusive<Self>
fn exhausted_range() -> RangeInclusive<Self>
Source§impl<T: FiniteFloat> Ord for Finite<T>
impl<T: FiniteFloat> Ord for Finite<T>
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl<T: FiniteFloat> PartialOrd for Finite<T>
impl<T: FiniteFloat> PartialOrd for Finite<T>
Auto Trait Implementations§
impl<T> Freeze for Finite<T>where
T: Freeze,
impl<T> RefUnwindSafe for Finite<T>where
T: RefUnwindSafe,
impl<T> Send for Finite<T>
impl<T> Sync for Finite<T>
impl<T> Unpin for Finite<T>where
T: Unpin,
impl<T> UnsafeUnpin for Finite<T>where
T: UnsafeUnpin,
impl<T> UnwindSafe for Finite<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more