Expand description
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:
-
Extentrepresents an inclusive range of numbers, where number isN:PrimIntfrom 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! -
Extentuses exactly 2 numbers and no extra flags or wasted space. -
Extentcan represent empty ranges. Empty ranges are represented with a normalized form of{lo=1, hi=0}. This is the only case for whichlo > hiand is only constructable via the static functionemptyor the IO-oriented functionnew_unchecked. Typical accessors for endpointslo()andhi()return anOption<N>withNonein 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 <= hiinvariant. -
All nonempty cases have
lo <= hienforced innew. If you passhi > lotonew, 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_uncheckedwhich will not swap, only normalize unordered ranges toempty(), and is also unsafe. -
ExtentimplementsCopy(and everything else standard). -
Extentdoes not implementIterator, but it has anitermethod that copiesExtentintoExtentIter, which does implementIterator. -
There is also an
ExtentRevIterthat 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”.