extent
This is an alternative to std::ops::{Range,RangeInclusive}
, avoiding the quirks of those types (non-Copy
, inability to produce empty inclusive ranges without extra bool, directly implementing Iterator
, etc). See https://ridiculousfish.com/blog/posts/least-favorite-rust-type.html and https://kaylynn.gay/blog/post/rust_ranges_and_suffering for its litany of sins.
I was coincidentally writing this type in one of my own crates today when I saw the second post go by, so I figured I'd split it out and post it as a crate others can use. It has some quirks and limitations of its own but it suits my needs better than the builtins. Here are the choices I made:
-
Extent
represents an inclusive range of numbers, where number isN:PrimInt
from the (fairly standard) num-traits crate. It is inclusive because (at least the most obvious representations of) exclusive ranges can't represent the maximum number of a number-type, which in my experience one fairly often needs to represent! -
Extent
uses exactly 2 numbers and no extra flags or wasted space. -
Extent
can represent empty ranges. Empty ranges are represented with a normalized form of{lo=1, hi=0}
. This is the only case for whichlo > hi
and is only constructable via the static functionempty
or the IO-oriented functionnew_unchecked
. Typical accessors for endpointslo()
andhi()
return anOption<N>
withNone
in the empty case. If you want the raw form (eg. for doing IO) you can calllo_unchecked()
orhi_unchecked()
, which are marked unsafe as they do not reflect the significantlo <= hi
invariant. -
All nonempty cases have
lo <= hi
enforced innew
. If you passhi > lo
tonew
, the values are swapped (i.e. you can construct from either order of points; they get stored in order). If you are constructing from raw IO values you can donew_unchecked
which will not swap, only normalize unordered ranges toempty()
, and is also unsafe. -
Extent
implementsCopy
(and everything else standard). -
Extent
does not implementIterator
, but it has aniter
method that copiesExtent
intoExtentIter
, which does implementIterator
. -
There is also an
ExtentRevIter
that counts down. -
Some basic set-like operators are provided (union, intersection, contains) but nothing too fancy.
Patches are welcome to enrich this further, though I will try to keep it fairly simple and focused on the use-case of number-ranges, not "arbitrary thing ranges".
License: MIT OR Apache-2.0