pub enum Bound {
Inclusive,
Exclusive,
}Expand description
Does a search from an anchor consider the anchor itself?
This existed as a choice between two function names (step vs
step_inclusive) plus, at one call site, a saturating_sub(1) that tried
to convert one into the other by arithmetic. Both mistakes are the same
mistake, and both are removed by making the bound a value:
- naming it forces the caller to state intent instead of remembering which function is which;
Bound::first_matchingnever subtracts, so the “back up one to include the anchor” trick — which cannot back up past 0, and therefore made a match at offset 0 unreachable — has nowhere to live.
Variants§
Inclusive
The anchor counts. /foo sitting ON a foo finds that one.
Exclusive
The anchor does not count. n advances off the current match.
Implementations§
Source§impl Bound
impl Bound
Sourcepub const fn admits_forward(self, candidate: usize, anchor: usize) -> bool
pub const fn admits_forward(self, candidate: usize, anchor: usize) -> bool
Does candidate lie at-or-after anchor under this bound?
Sourcepub const fn admits_backward(self, candidate: usize, anchor: usize) -> bool
pub const fn admits_backward(self, candidate: usize, anchor: usize) -> bool
Does candidate lie at-or-before anchor under this bound?
Sourcepub fn first_matching(
self,
starts: &[usize],
anchor: usize,
forward: bool,
) -> Option<usize>
pub fn first_matching( self, starts: &[usize], anchor: usize, forward: bool, ) -> Option<usize>
The index of the first ascending starts entry this bound admits,
searching forward from anchor.
Total, and correct at 0 by construction — there is no subtraction
to saturate. That is the seal on the measured bug: an inclusive search
used to be spelled step(from - 1), and 0 - 1 saturates back to 0,
so a match at the very start of the file could never be found.
Source§impl Bound
impl Bound
Sourcepub fn step_wrapping(
self,
starts: &[usize],
anchor: usize,
forward: bool,
) -> Option<Landing>
pub fn step_wrapping( self, starts: &[usize], anchor: usize, forward: bool, ) -> Option<Landing>
first_matching, wrapping at the ends.
first_matching answers “what is next” and returns None at the end.
Both callers want “what is next, wrapping” — and both also want to
TELL the reader that it wrapped. Doing it here means search and result
navigation cannot drift into wrapping differently, or into one of them
going quiet about it.
None only when starts is empty: with anything to land on, a
wrapping step always lands.