1use crate::core::Node;
2use crate::list::api::List;
3use crate::list::common::ListCommon;
4
5pub struct SortedList<T> {
26 state: ListCommon<T>,
27}
28
29impl<T> SortedList<T> {
30 pub fn new() -> Self {
32 Self {
33 state: ListCommon::new(),
34 }
35 }
36
37 pub fn from_slice(slice: &[T]) -> Self
41 where
42 T: Clone + PartialOrd,
43 {
44 let mut list = SortedList::new();
45 for value in slice.iter() {
46 list.push((*value).clone());
47 }
48 list
49 }
50
51 pub fn to_vec(&self) -> Vec<T>
55 where
56 T: Clone,
57 {
58 self.state.to_vec()
59 }
60
61 fn find_if(&self, predicate: impl Fn(&T) -> bool) -> Option<usize>
66 where
67 T: PartialOrd,
68 {
69 self.state.find_if(predicate)
70 }
71
72 fn insert_in_middle(&mut self, ptr: *mut Node<T>)
74 where
75 T: PartialOrd,
76 {
77 let mut prev = self.state.head;
78 unsafe {
79 let mut next = (*prev).next;
80
81 while !next.is_null() {
82 if (*ptr).payload < (*next).payload {
83 (*prev).next = ptr;
84 (*ptr).next = next;
85 return;
86 }
87 prev = next;
88 next = (*next).next;
89 }
90 }
91 }
92}
93
94impl<'a, T: 'a> List<'a, T> for SortedList<T>
95where
96 T: PartialOrd,
97{
98 fn len(&self) -> usize {
102 self.state.len()
103 }
104
105 fn head(&self) -> Option<&T> {
109 self.state.head()
110 }
111
112 fn last(&self) -> Option<&T> {
116 self.state.last()
117 }
118
119 fn iter(&self) -> impl Iterator<Item = &'a T> {
121 self.state.iter()
122 }
123
124 fn iter_mut(&mut self) -> impl Iterator<Item = &'a mut T> {
126 self.state.iter_mut()
127 }
128
129 fn into_iter(self) -> impl Iterator<Item = T> {
131 self.state.into_iter()
132 }
133
134 fn push(&mut self, payload: T) {
138 let ptr = Box::into_raw(Box::new(Node::new(payload)));
139
140 if self.is_empty() {
141 self.state.head = ptr;
142 self.state.last = ptr;
143 } else {
144 unsafe {
145 if (*ptr).payload <= (*self.state.head).payload {
147 (*ptr).next = self.state.head;
148 self.state.head = ptr;
149 }
150 else if (*self.state.last).payload <= (*ptr).payload {
152 (*self.state.last).next = ptr;
153 self.state.last = ptr;
154 }
155 else {
157 self.insert_in_middle(ptr);
158 }
159 }
160 }
161 self.state.size += 1;
162 }
163
164 fn pop_back(&mut self) -> Option<T> {
168 self.state.pop_back()
169 }
170
171 fn pop_front(&mut self) -> Option<T> {
175 self.state.pop_front()
176 }
177
178 fn remove(&mut self, index: usize) -> crate::Result<T> {
183 self.state.remove(index)
184 }
185
186 fn find(&self, value: &T) -> Option<usize>
191 where T: PartialEq<T>
192 {
193 for (index, payload) in self.iter().enumerate() {
194 if payload == value {
195 return Some(index);
196 }
197 if payload > value {
200 break; }
202 }
203 None
204 }
205}
206
207#[cfg(test)]
208mod tests {
209 use super::*;
210
211 #[test]
212 fn test_from_slice() {
213 let list = SortedList::from_slice(&[2, 1, 5, 4, 3]);
214 assert_eq!(list.to_vec(), [1, 2, 3, 4, 5]);
215 }
216
217 mod push {
218 use std::cmp::Ordering;
219 use super::*;
220
221 #[test]
222 fn test_push_empty_list() {
223 let mut list = SortedList::<i32>::new();
224
225 list.push(42);
226
227 assert_eq!(list.len(), 1, "list should have one element after push");
228 assert_eq!(list.to_vec(), vec![42], "single element should be correctly inserted");
229 assert_eq!(list.state.head, list.state.last, "head and last should point to the same node in single-element list");
230 }
231
232 #[test]
233 fn test_push_to_beginning() {
234 let mut list = SortedList::from_slice(&[2, 3, 4]);
235
236 list.push(1);
237
238 let values = list.to_vec();
239 assert_eq!(values, vec![1, 2, 3, 4], "element smaller than all existing should be inserted at beginning");
240 unsafe {
241 assert_eq!((*list.state.head).payload, 1, "head should point to newly inserted smallest element");
242 }
243 }
244
245 #[test]
246 fn test_push_to_end() {
247 let mut list = SortedList::from_slice(&[1, 2, 3]);
248
249 list.push(4);
250
251 let values = list.to_vec();
252 assert_eq!(values, vec![1, 2, 3, 4], "element larger than all existing should be inserted at end");
253 unsafe {
254 assert_eq!((*list.state.last).payload, 4, "last should point to newly inserted largest element");
255 }
256 }
257
258 #[test]
259 fn test_push_in_middle() {
260 let mut list = SortedList::from_slice(&[1, 3, 5]);
261
262 list.push(2);
263
264 let values = list.to_vec();
265 assert_eq!(values, vec![1, 2, 3, 5], "element should be inserted in correct middle position");
266 }
267
268 #[test]
269 fn test_push_duplicate_values() {
270 let mut list = SortedList::from_slice(&[1, 3, 5]);
271
272 list.push(3);
273
274 let values = list.to_vec();
275 assert_eq!(values, vec![1, 3, 3, 5], "duplicate values should be inserted and preserved");
276 }
277
278 #[test]
279 fn test_push_multiple_elements_in_random_order() {
280 let mut list = SortedList::new();
281
282 list.push(5);
284 list.push(1);
285 list.push(3);
286 list.push(2);
287 list.push(4);
288
289 let values = list.to_vec();
290 assert_eq!(values, vec![1, 2, 3, 4, 5], "elements inserted in random order should result in sorted list");
291 }
292
293 #[test]
294 fn test_push_updates_size_correctly() {
295 let mut list = SortedList::new();
296
297 assert_eq!(list.len(), 0, "new list should have size 0");
298
299 list.push(1);
300 assert_eq!(list.len(), 1, "size should be 1 after first push");
301
302 list.push(2);
303 assert_eq!(list.len(), 2, "size should be 2 after second push");
304
305 list.push(0);
306 assert_eq!(list.len(), 3, "size should be 3 after third push");
307 }
308
309 #[test]
310 fn test_push_string_data() {
311 let mut list = SortedList::new();
312
313 list.push("zebra".to_string());
314 list.push("apple".to_string());
315 list.push("banana".to_string());
316
317 let values = list.to_vec();
318 assert_eq!(
319 values,
320 vec!["apple".to_string(), "banana".to_string(), "zebra".to_string()],
321 "strings should be sorted alphabetically"
322 );
323 }
324
325 #[test]
326 fn test_push_large_numbers() {
327 let mut list = SortedList::new();
328
329 list.push(1_000_000);
330 list.push(-1_000_000);
331 list.push(0);
332
333 let values = list.to_vec();
334 assert_eq!(values, vec![-1_000_000, 0, 1_000_000], "large positive and negative numbers should be sorted correctly");
335 }
336
337 #[test]
338 fn test_push_after_clear() {
339 let mut list = SortedList::from_slice(&[1, 2, 3]);
340 list.clear();
341
342 assert_eq!(list.len(), 0, "list should be empty after clear");
343
344 list.push(5);
345
346 let values = list.to_vec();
347 assert_eq!(values, vec![5], "push after clear should work correctly");
348 assert_eq!(list.len(), 1, "size should be 1 after push following clear");
349 }
350
351 #[test]
352 fn test_push_with_custom_ord_type() {
353 #[derive(Clone, Debug, PartialEq)]
354 struct Point {
355 x: i32,
356 y: i32,
357 }
358
359 impl PartialOrd for Point {
360 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
361 self.x.partial_cmp(&other.x)
362 }
363 }
364
365 let mut list = SortedList::new();
366 list.push(Point { x: 3, y: 1 });
367 list.push(Point { x: 1, y: 5 });
368 list.push(Point { x: 2, y: 8 });
369
370 let values = list.to_vec();
371 assert_eq!(values.len(), 3, "custom Ord type should be handled correctly");
372 assert_eq!(values[0].x, 1, "should be sorted by x coordinate");
373 assert_eq!(values[1].x, 2, "should be sorted by x coordinate");
374 assert_eq!(values[2].x, 3, "should be sorted by x coordinate");
375 }
376 }
377
378 mod find {
379 use super::*;
380
381 fn create_list_from_slice<T: Clone + PartialOrd>(values: &[T]) -> SortedList<T> {
383 SortedList::from_slice(values)
384 }
385
386 #[test]
387 fn test_find_empty_list() {
388 let list: SortedList<i32> = SortedList::new();
389 let result = list.find(&42);
390
391 assert_eq!(result, None, "should return None for empty list");
392 }
393
394 #[test]
395 fn test_find_element_at_beginning() {
396 let list = create_list_from_slice(&[1, 2, 3, 4, 5]);
397 let result = list.find(&1);
398
399 assert_eq!(result, Some(0), "should find element at index 0");
400 }
401
402 #[test]
403 fn test_find_element_in_middle() {
404 let list = create_list_from_slice(&[10, 20, 30, 40, 50]);
405 let result = list.find(&30);
406
407 assert_eq!(result, Some(2), "should find element in the middle and return correct index");
408 }
409
410 #[test]
411 fn test_find_element_at_end() {
412 let list = create_list_from_slice(&[5, 10, 15, 20]);
413 let result = list.find(&20);
414
415 assert_eq!(result, Some(3), "should find element at the end and return correct index");
416 }
417
418 #[test]
419 fn test_find_non_existent_element_smaller_than_all() {
420 let list = create_list_from_slice(&[10, 20, 30, 40]);
421 let result = list.find(&5);
422
423 assert_eq!(result, None, "should return None when searching for element smaller than all elements");
424 }
425
426 #[test]
427 fn test_find_non_existent_element_larger_than_all() {
428 let list = create_list_from_slice(&[10, 20, 30, 40]);
429 let result = list.find(&50);
430
431 assert_eq!(result, None, "should return None and use early exit for element larger than all");
433 }
434
435 #[test]
436 fn test_find_non_existent_element_between_values() {
437 let list = create_list_from_slice(&[10, 20, 30, 40]);
438 let result = list.find(&25);
439
440 assert_eq!(result, None, "should use early exit when value would be between existing elements");
442 }
443
444 #[test]
445 fn test_find_first_occurrence_of_duplicate() {
446 let list = create_list_from_slice(&[1, 2, 2, 3, 2]);
447 let result = list.find(&2);
448
449 assert_eq!(result, Some(1), "should return index of first occurrence when duplicates exist");
450 }
451
452 #[test]
453 fn test_find_single_element_match() {
454 let list = create_list_from_slice(&[42]);
455 let result = list.find(&42);
456
457 assert_eq!(result, Some(0), "should find matching element in single-element list");
458 }
459
460 #[test]
461 fn test_find_single_element_no_match() {
462 let list = create_list_from_slice(&[42]);
463 let result = list.find(&100);
464
465 assert_eq!(result, None, "should return None in single-element list when no match");
466 }
467
468 #[test]
469 fn test_find_with_string_data() {
470 let strings = vec!["apple", "banana", "cherry", "date"];
471 let list = create_list_from_slice(&strings);
472
473 let result = list.find(&"cherry");
474 assert_eq!(result, Some(2), "should find string element at correct index");
475
476 let result2 = list.find(&"grape");
477 assert_eq!(result2, None, "should return None for non‑existent string");
478 }
479
480 #[test]
481 fn test_find_early_exit_efficiency_hint() {
482 let large_values: Vec<i32> = (0..1000).map(|x| x * 2).collect(); let list = create_list_from_slice(&large_values);
485
486 let result = list.find(&1); assert_eq!(result, None, "should efficiently exit early when value is between first elements");
490
491 }
494
495 #[test]
496 fn test_find_custom_type() {
497 #[derive(PartialEq, PartialOrd, Debug, Clone)]
498 struct Person {
499 name: String,
500 age: u32,
501 }
502
503 let people = vec![
504 Person { name: "Alice".to_string(), age: 25 },
505 Person { name: "Bob".to_string(), age: 30 },
506 Person { name: "Charlie".to_string(), age: 35 },
507 ];
508 let list = create_list_from_slice(&people);
509
510 let target = Person { name: "Bob".to_string(), age: 30 };
511 let result = list.find(&target);
512 assert_eq!(result, Some(1), "should find custom type by full equality");
513
514 let nonexistent = Person { name: "David".to_string(), age: 40 };
515 let result2 = list.find(&nonexistent);
516 assert_eq!(result2, None, "should return None for non‑existent custom type");
517 }
518
519 #[test]
520 fn test_find_preserves_list_integrity() {
521 let values = vec![1, 3, 5, 7, 9];
522 let list = create_list_from_slice(&values);
523
524 let original_vec = list.to_vec();
526
527 let _result1 = list.find(&3);
529 let _result2 = list.find(&6); let _result3 = list.find(&9);
531
532 assert_eq!(list.to_vec(), original_vec, "find operation should not modify the original list");
534 assert_eq!(list.len(), 5, "list length should remain unchanged after find operations");
535 }
536
537 #[test]
538 fn test_find_on_list_with_negative_numbers() {
539 let list = create_list_from_slice(&[-10, -5, 0, 5, 10]);
540
541 assert_eq!(list.find(&-5), Some(1), "should find negative number at correct index");
542 assert_eq!(list.find(&0), Some(2), "should find zero at correct index");
543 assert_eq!(list.find(&15), None, "should return None for value larger than all elements");
544 assert_eq!(list.find(&-15), None, "should return None for value smaller than all elements");
545 }
546 }
547}