Skip to main content

Range

Struct Range 

Source
pub struct Range { /* private fields */ }
Expand description

What an integer value can be.

A few disjoint intervals over the unsigned reading of the bit pattern, and the bits that are known, at a width. The two halves are kept consistent with each other by Range::narrow, so a range that came out of any constructor here has intervals no wider than its bits allow and bits no vaguer than its intervals prove.

Implementations§

Source§

impl Range

Source

pub const fn empty(width: u32) -> Self

Nothing at all, which is the range of a value on a path that is never taken.

Source

pub const fn full(width: u32) -> Self

Every value of this width, which is what is known about a value nothing has said anything about.

Source

pub fn of(ty: Type) -> Self

Everything a value of this type can be.

A type that is not a scalar integer gets the widest full range, because saying nothing about a vector or a pointer is always true and this module is about integers.

Source

pub fn exactly(value: u128, width: u32) -> Self

One value.

Source

pub fn between(lo: u128, hi: u128, width: u32) -> Self

Every bit pattern from one bound to the other, inclusive, wrapping if the low bound is above the high one.

The wrapping case is what a signed interval becomes here: [-5, 5] in eight bits is [0xfb, 0x05], which is the two intervals [0, 5] and [0xfb, 0xff], and taking the bounds in that order is how a caller says so without having to split it itself.

Source

pub fn signed_between(lo: i128, hi: i128, width: u32) -> Self

Every value from one signed bound to the other, inclusive.

The bounds are read as signed numbers of that width and the intervals come out over bit patterns, so [-5, 5] in eight bits becomes [0, 5] and [0xfb, 0xff] on its own. A signed interval is always one wrapping interval in the unsigned domain, so nothing is lost on the way through.

Source

pub fn other_than(value: u128, width: u32) -> Self

Every value except this one.

Range::other_than(0, width) is the non-zero range, which section 10.2 calls the single most useful range fact in a C compiler.

Source

pub fn from_pairs(pairs: &[(u128, u128)], width: u32) -> Self

A range from intervals that need not be sorted, disjoint or in bounds.

This is the way in from an operation that produced a handful of intervals and does not want to think about their order. Anything beyond PAIRS of them after merging collapses to the hull of the ones that did not fit, which loses precision and never soundness.

Source

pub fn narrow(self, bits: Bits) -> Self

The same intervals with these bits also known.

The two refine each other here and nowhere else, which is what section 10.2 asks for. An interval whose ends the bits rule out is pulled in to the nearest value the bits allow, the bits are then recomputed from what survived, and a range whose halves contradict each other comes back empty.

Source

pub const fn width(self) -> u32

The width the values are, in bits.

Source

pub fn pairs(&self) -> &[(u128, u128)]

The intervals, ascending and disjoint.

Source

pub const fn bits(self) -> Bits

The bits that are known about every value in it.

Source

pub fn list(self, limit: usize) -> Option<Vec<u128>>

Every value in it, or None when there are more than that many.

For walking a shift count or a switch selector, where the range is usually a handful of values and enumerating them gives an exact answer that reasoning about the bounds would round off. The limit is what stops that turning into a walk over four billion of them.

Source

pub const fn is_empty(self) -> bool

Whether nothing is in it, which means the value is on a path that is never taken.

Source

pub fn is_full(self) -> bool

Whether everything is in it, which means nothing is known.

Source

pub fn singleton(self) -> Option<u128>

The one value in it, if there is exactly one.

Source

pub fn contains(self, value: u128) -> bool

Whether this value is in it.

A range is its intervals and its bits together, so this asks both. A value inside one of the intervals whose bits are wrong is not in the range, which is what makes “somewhere in [0, 1023] and a multiple of eight” mean the hundred and twenty eight values it says rather than the thousand and twenty four the interval alone would.

Source

pub fn unsigned_bounds(self) -> Option<(u128, u128)>

The least and greatest, read as unsigned, or None when the range is empty.

Source

pub fn signed_bounds(self) -> Option<(i128, i128)>

The least and greatest, read as signed at this width, or None when the range is empty.

The intervals are over bit patterns, so the signed answer is not the first and last of them. Everything at or above the sign boundary is negative and sorts below everything under it, so the least signed value is the first pattern at or above the boundary when there is one and the first pattern otherwise. That reordering is the whole of what the unsigned domain costs, and it is eleven lines.

Source

pub fn nonzero(self) -> bool

Whether nothing in it is zero.

The fact a null check produces and the fact a division needs, which is why it has a name of its own rather than being spelled out at every call.

Source

pub fn fits_unsigned(self, bits: u32) -> bool

Whether every value in it fits in that many bits, read as unsigned.

Source

pub fn fits_signed(self, bits: u32) -> bool

Whether every value in it fits in that many bits, read as signed.

Source

pub fn union(self, other: Self) -> Self

Everything in either of them.

§Panics

Panics if the two are of different widths, since a value is one width and combining the ranges of two that are not is a question with no answer.

Source

pub fn intersect(self, other: Self) -> Self

Everything in both of them.

§Panics

Panics if the two are of different widths.

Source

pub fn invert(self) -> Self

Everything of this width that is not in it.

Trait Implementations§

Source§

impl Clone for Range

Source§

fn clone(&self) -> Range

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Range

Source§

impl Debug for Range

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Range

Source§

impl PartialEq for Range

Source§

fn eq(&self, other: &Range) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Range

Auto Trait Implementations§

§

impl Freeze for Range

§

impl RefUnwindSafe for Range

§

impl Send for Range

§

impl Sync for Range

§

impl Unpin for Range

§

impl UnsafeUnpin for Range

§

impl UnwindSafe for Range

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.