vstd_extra/external/range.rs
1use core::ops::Range;
2use vstd::prelude::*;
3
4verus! {
5
6/// Length of a `Range<usize>`. Malformed ranges (`start > end`) are length 0,
7/// matching `ExactSizeIterator::len` for `Range<A: Step>` where `Step::steps_between`
8/// returns `None` on `end < start`, collapsed to 0.
9pub open spec fn range_usize_len_spec(r: &Range<usize>) -> usize {
10 if r.start < r.end {
11 (r.end - r.start) as usize
12 } else {
13 0usize
14 }
15}
16
17/// Exec-mode `len` for a `Range<usize>`: use in place of `r.len()` which is an
18/// `ExactSizeIterator` provided method and can't be specced with
19/// `assume_specification`.
20#[verifier::when_used_as_spec(range_usize_len_spec)]
21pub fn range_usize_len(r: &Range<usize>) -> (ret: usize)
22 ensures
23 ret == range_usize_len_spec(r),
24{
25 if r.start < r.end {
26 r.end - r.start
27 } else {
28 0
29 }
30}
31
32/// Whether a `Range<usize>` is empty. Malformed ranges (`start > end`) are empty.
33pub open spec fn range_usize_is_empty_spec(r: &Range<usize>) -> bool {
34 !(r.start < r.end)
35}
36
37/// Exec-mode `is_empty` for a `Range<usize>`: use in place of `r.is_empty()`
38/// which needs `Idx: PartialOrd<Idx>` bound that doesn't round-trip cleanly
39/// through `assume_specification`.
40#[verifier::when_used_as_spec(range_usize_is_empty_spec)]
41pub fn range_usize_is_empty(r: &Range<usize>) -> (ret: bool)
42 ensures
43 ret == range_usize_is_empty_spec(r),
44{
45 !(r.start < r.end)
46}
47
48} // verus!