diff --git a/deque/deque.mbt b/deque/deque.mbt index b513d7f4f..140ad339f 100644 --- a/deque/deque.mbt +++ b/deque/deque.mbt @@ -661,6 +661,59 @@ pub fn iter2[A](self : T[A]) -> Iter2[Int, A] { }) } +///| +pub fn rev_iter[A](self : T[A]) -> Iter[A] { + Iter::new(fn(yield_) { + guard not(self.is_empty()) else { IterContinue } + let { head, buf, len, .. } = self + let cap = buf.length() + let head_len = cap - head + if head_len >= len { + for i = head + len - 1; i >= head; i = i - 1 { + guard let IterContinue = yield_(buf[i]) else { x => return x } + + } + } else { + for i = len - head_len - 1; i >= 0; i = i - 1 { + guard let IterContinue = yield_(buf[i]) else { x => return x } + + } + for i = cap - 1; i >= head; i = i - 1 { + guard let IterContinue = yield_(buf[i]) else { x => return x } + + } + } + IterContinue + }) +} + +///| +pub fn rev_iter2[A](self : T[A]) -> Iter2[Int, A] { + Iter2::new(fn(yield_) { + guard not(self.is_empty()) else { IterContinue } + let { head, buf, len, .. } = self + let cap = buf.length() + let head_len = cap - head + let mut j = 0 + if head_len >= len { + for i = head + len - 1; i >= head; i = i - 1 { + guard let IterContinue = yield_(j, buf[i]) else { x => return x } + j += 1 + } + } else { + for i = len - head_len - 1; i >= 0; i = i - 1 { + guard let IterContinue = yield_(j, buf[i]) else { x => return x } + j += 1 + } + for i = cap - 1; i >= head; i = i - 1 { + guard let IterContinue = yield_(j, buf[i]) else { x => return x } + j += 1 + } + } + IterContinue + }) +} + ///| pub fn T::from_iter[A](iter : Iter[A]) -> T[A] { let dq = T::new() diff --git a/deque/deque.mbti b/deque/deque.mbti index 16a67419a..244d79743 100644 --- a/deque/deque.mbti +++ b/deque/deque.mbti @@ -35,6 +35,8 @@ impl T { reserve_capacity[A](Self[A], Int) -> Unit rev_each[A](Self[A], (A) -> Unit) -> Unit rev_eachi[A](Self[A], (Int, A) -> Unit) -> Unit + rev_iter[A](Self[A]) -> Iter[A] + rev_iter2[A](Self[A]) -> Iter2[Int, A] search[A : Eq](Self[A], A) -> Int? shrink_to_fit[A](Self[A]) -> Unit unsafe_pop_back[A](Self[A]) -> Unit diff --git a/deque/deque_test.mbt b/deque/deque_test.mbt index cdf406c0b..8160809bd 100644 --- a/deque/deque_test.mbt +++ b/deque/deque_test.mbt @@ -129,7 +129,7 @@ test "mapi" { inspect!(dve.mapi(fn(_idx, x) { x }), content="@deque.of([])") } -test "iter_rev" { +test "rev_each" { let mut i = 6 let mut failed = false @deque.of([1, 2, 3, 4, 5]).rev_each(fn(elem) { @@ -141,7 +141,7 @@ test "iter_rev" { assert_false!(failed) } -test "iter_revi" { +test "rev_eachi" { let mut i = 6 let mut j = 0 let mut failed = false @@ -447,6 +447,33 @@ test "iter2 when tail needs to wrap around" { inspect!(dq.iter2().to_array(), content="[(0, 2), (1, 3)]") } +test "rev_iter when head needs to wrap around" { + let dq = @deque.new(capacity=4) + dq.push_back(1) + dq.unsafe_pop_front() + dq.push_back(2) + dq.unsafe_pop_front() + for i in 3..=6 { + dq.push_back(i) + } + inspect!(dq.rev_iter().to_array(), content="[6, 5, 4, 3]") +} + +test "rev_iter2 when head needs to wrap around" { + let dq = @deque.new(capacity=4) + dq.push_back(1) + dq.unsafe_pop_front() + dq.push_back(2) + dq.unsafe_pop_front() + for i in 3..=6 { + dq.push_back(i) + } + inspect!( + dq.rev_iter2().to_array(), + content="[(0, 6), (1, 5), (2, 4), (3, 3)]", + ) +} + test "deque push_front when empty" { let d = @deque.of([0, 1]) ignore(d.pop_back())