memx/iter/
iter_chr_dbl.rs

1#[inline]
2pub fn memchr_dbl_iter(haystack: &[u8], needle1: u8, needle2: u8) -> MemchrDblIter<'_> {
3    MemchrDblIter::new(haystack, needle1, needle2)
4}
5
6pub struct MemchrDblIter<'a> {
7    haystack: &'a [u8],
8    needle1: u8,
9    needle2: u8,
10    position: usize, // 0: idx is -1, 1: idx is 0, 2: idx is 1
11}
12impl MemchrDblIter<'_> {
13    #[inline]
14    pub fn new(haystack: &[u8], needle1: u8, needle2: u8) -> MemchrDblIter<'_> {
15        MemchrDblIter {
16            needle1,
17            needle2,
18            haystack,
19            position: 0,
20        }
21    }
22}
23impl Iterator for MemchrDblIter<'_> {
24    type Item = usize;
25    #[inline]
26    fn next(&mut self) -> Option<usize> {
27        if self.position > self.haystack.len() {
28            return None;
29        }
30        match crate::memchr_dbl(&self.haystack[self.position..], self.needle1, self.needle2) {
31            Some(idx) => {
32                let found = self.position + idx;
33                self.position = self.position + idx + 1;
34                Some(found)
35            }
36            None => {
37                self.position = self.haystack.len() + 1;
38                None
39            }
40        }
41    }
42    #[inline]
43    fn size_hint(&self) -> (usize, Option<usize>) {
44        (0, Some(self.haystack.len()))
45    }
46}
47
48impl DoubleEndedIterator for MemchrDblIter<'_> {
49    #[inline]
50    fn next_back(&mut self) -> Option<Self::Item> {
51        if self.position == 0 {
52            return None;
53        }
54        match crate::memrchr_dbl(
55            &self.haystack[..(self.position - 1)],
56            self.needle1,
57            self.needle2,
58        ) {
59            Some(idx) => {
60                self.position = idx + 1;
61                Some(idx)
62            }
63            None => {
64                self.position = 0;
65                None
66            }
67        }
68    }
69}