Skip to content

Commit fea4d8c

Browse files
authored
Merge pull request #43 from orxfun/fix/#42-backward-iter-from-back-node
bug with backward iterators created from the back node is fixed
2 parents e973e12 + 2a365fc commit fea4d8c

File tree

4 files changed

+101
-62
lines changed

4 files changed

+101
-62
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "orx-linked-list"
3-
version = "3.7.0"
3+
version = "3.8.0"
44
edition = "2024"
55
authors = ["orxfun <orx.ugur.arikan@gmail.com>"]
66
description = "A linked list implementation with unique features and an extended list of constant time methods providing high performance traversals and mutations."

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ pub mod pointers;
2929
mod type_aliases;
3030
mod variant;
3131

32+
pub use list::List;
3233
pub use list::ends_traits::*;
3334
pub use list::iter_traits::*;
3435
pub use list::slice::{ListSlice, ListSliceMut};
35-
pub use list::List;
3636
pub use orx_selfref_col::{MemoryPolicy, NodeIdx, NodeIdxError};
3737
pub use type_aliases::{
3838
DoublyIdx, DoublyList, DoublyListLazy, DoublyListSlice, DoublyListSliceLazy,

src/list/iter_traits/doubly_iterable.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::{
2+
Doubly, DoublyIdx,
23
iter::{DoublyIter, DoublyIterPtr, DoublyLinkIter},
34
list::helper_traits::HasDoublyEnds,
45
pointers::DoublyPtr,
56
type_aliases::{BACK_IDX, FRONT_IDX, OOB},
6-
Doubly, DoublyIdx,
77
};
88
use core::iter::{Chain, Rev};
99
use orx_pinned_vec::PinnedVec;
@@ -283,7 +283,7 @@ where
283283
M: 'a,
284284
{
285285
let b = self.col().try_get_ptr(idx).expect(OOB);
286-
let a = self.ends().get(BACK_IDX).cloned();
286+
let a = self.ends().get(FRONT_IDX).cloned();
287287
DoublyIter::new(self.col(), a, Some(b)).rev()
288288
}
289289

tests/iter_from.rs

+97-58
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
11
use orx_linked_list::*;
22

3-
#[test]
4-
fn iter_from_singly() {
5-
let mut list = SinglyList::new();
6-
let mut idx42 = None;
7-
for i in 0..324 {
8-
let idx = list.push_front(i.to_string());
9-
if i == 42 {
10-
idx42 = Some(idx)
11-
}
12-
}
13-
14-
let idx42 = idx42.unwrap();
15-
16-
let vec: Vec<_> = list.iter().cloned().collect();
17-
let index_of_42 = vec
3+
fn test_singly_iter_from(
4+
list: &SinglyList<String>,
5+
vec: &[String],
6+
value: usize,
7+
idx: NodeIdx<Singly<String>>,
8+
) {
9+
let position = vec
1810
.iter()
1911
.enumerate()
20-
.find(|(_, x)| x == &&42.to_string())
12+
.find(|(_, x)| x == &&value.to_string())
2113
.unwrap()
2214
.0;
2315

24-
let vec_slice = &vec[index_of_42..];
25-
let mut list_slice = list.iter_from(&idx42);
16+
let vec_slice = &vec[position..];
17+
let mut list_slice = list.iter_from(&idx);
2618
#[cfg(feature = "validation")]
2719
list.validate();
2820

@@ -34,37 +26,51 @@ fn iter_from_singly() {
3426
assert!(list_slice.next().is_none());
3527
}
3628

37-
#[test]
38-
fn iter_from_doubly() {
39-
let mut list = DoublyList::new();
40-
let mut idx42 = None;
41-
for i in 0..324 {
42-
let idx = match i % 3 == 0 {
43-
true => list.push_back(i.to_string()),
44-
false => list.push_front(i.to_string()),
45-
};
29+
fn test_doubly_iter_from(
30+
list: &DoublyList<String>,
31+
vec: &[String],
32+
value: usize,
33+
idx: NodeIdx<Doubly<String>>,
34+
) {
35+
let position = vec
36+
.iter()
37+
.enumerate()
38+
.find(|(_, x)| x == &&value.to_string())
39+
.unwrap()
40+
.0;
4641

47-
if i == 42 {
48-
idx42 = Some(idx)
49-
}
42+
let vec_slice = &vec[position..];
43+
let mut list_slice = list.iter_from(&idx);
44+
#[cfg(feature = "validation")]
45+
list.validate();
46+
47+
for x in vec_slice {
48+
let value = list_slice.next().unwrap();
49+
assert_eq!(x, value);
5050
}
5151

52-
let idx42 = idx42.unwrap();
52+
assert!(list_slice.next().is_none());
53+
}
5354

54-
let vec: Vec<_> = list.iter().cloned().collect();
55-
let index_of_42 = vec
55+
fn test_doubly_iter_backward_from(
56+
list: &DoublyList<String>,
57+
vec: &[String],
58+
value: usize,
59+
idx: NodeIdx<Doubly<String>>,
60+
) {
61+
let position = vec
5662
.iter()
5763
.enumerate()
58-
.find(|(_, x)| x == &&42.to_string())
64+
.find(|(_, x)| x == &&value.to_string())
5965
.unwrap()
6066
.0;
6167

62-
let vec_slice = &vec[index_of_42..];
63-
let mut list_slice = list.iter_from(&idx42);
68+
let vec_slice = &vec[0..=position];
69+
let mut list_slice = list.iter_backward_from(&idx);
6470
#[cfg(feature = "validation")]
6571
list.validate();
6672

67-
for x in vec_slice {
73+
for x in vec_slice.iter().rev() {
6874
let value = list_slice.next().unwrap();
6975
assert_eq!(x, value);
7076
}
@@ -73,39 +79,72 @@ fn iter_from_doubly() {
7379
}
7480

7581
#[test]
76-
fn iter_backward_from_doubly() {
82+
fn iter_from_singly() {
83+
let mut list = SinglyList::new();
84+
let [mut idx_first, mut idx_last, mut idx42] = [None, None, None];
85+
for i in 0..324 {
86+
let idx = list.push_front(i.to_string());
87+
match i {
88+
0 => idx_first = Some(idx),
89+
42 => idx42 = Some(idx),
90+
323 => idx_last = Some(idx),
91+
_ => {}
92+
};
93+
}
94+
95+
let vec: Vec<_> = list.iter().cloned().collect();
96+
97+
test_singly_iter_from(&list, &vec, 0, idx_first.unwrap());
98+
test_singly_iter_from(&list, &vec, 323, idx_last.unwrap());
99+
test_singly_iter_from(&list, &vec, 42, idx42.unwrap());
100+
}
101+
102+
#[test]
103+
fn iter_from_doubly() {
77104
let mut list = DoublyList::new();
78-
let mut idx42 = None;
105+
let [mut idx_first, mut idx_last, mut idx42] = [None, None, None];
79106
for i in 0..324 {
80107
let idx = match i % 3 == 0 {
81108
true => list.push_back(i.to_string()),
82109
false => list.push_front(i.to_string()),
83110
};
84111

85-
if i == 42 {
86-
idx42 = Some(idx)
87-
}
112+
match i {
113+
0 => idx_first = Some(idx),
114+
42 => idx42 = Some(idx),
115+
323 => idx_last = Some(idx),
116+
_ => {}
117+
};
88118
}
89119

90-
let idx42 = idx42.unwrap();
91-
92120
let vec: Vec<_> = list.iter().cloned().collect();
93-
let index_of_42 = vec
94-
.iter()
95-
.enumerate()
96-
.find(|(_, x)| x == &&42.to_string())
97-
.unwrap()
98-
.0;
99121

100-
let vec_slice = &vec[0..=index_of_42];
101-
let mut list_slice = list.iter_backward_from(&idx42);
102-
#[cfg(feature = "validation")]
103-
list.validate();
122+
test_doubly_iter_from(&list, &vec, 0, idx_first.unwrap());
123+
test_doubly_iter_from(&list, &vec, 323, idx_last.unwrap());
124+
test_doubly_iter_from(&list, &vec, 42, idx42.unwrap());
125+
}
104126

105-
for x in vec_slice.iter().rev() {
106-
let value = list_slice.next().unwrap();
107-
assert_eq!(x, value);
127+
#[test]
128+
fn iter_backward_from_doubly() {
129+
let mut list = DoublyList::new();
130+
let [mut idx_first, mut idx_last, mut idx42] = [None, None, None];
131+
for i in 0..324 {
132+
let idx = match i % 3 == 0 {
133+
true => list.push_back(i.to_string()),
134+
false => list.push_front(i.to_string()),
135+
};
136+
137+
match i {
138+
0 => idx_first = Some(idx),
139+
42 => idx42 = Some(idx),
140+
323 => idx_last = Some(idx),
141+
_ => {}
142+
};
108143
}
109144

110-
assert!(list_slice.next().is_none());
145+
let vec: Vec<_> = list.iter().cloned().collect();
146+
147+
test_doubly_iter_backward_from(&list, &vec, 0, idx_first.unwrap());
148+
test_doubly_iter_backward_from(&list, &vec, 323, idx_last.unwrap());
149+
test_doubly_iter_backward_from(&list, &vec, 42, idx42.unwrap());
111150
}

0 commit comments

Comments
 (0)