1use std::fmt::{self, Debug, Display, Formatter};
2use std::hash::{Hash, Hasher};
3use std::marker::PhantomData;
4use std::mem;
5use std::ops::{Index, IndexMut};
6
7use derive_more::IsVariant;
8
9use super::{Iter, IterMut, Length, Node, NodePtr, ONE};
10use crate::collections::contiguous::Vector;
11use crate::collections::linked::cursor::{Cursor, CursorContents, CursorPosition, CursorState};
12#[doc(inline)]
13pub use crate::util::error::{CapacityOverflow, IndexOutOfBounds};
14use crate::util::result::ResultExtension;
15
16#[derive(PartialEq, Eq, Hash)]
43pub struct LinkedList<T> {
44 pub(crate) state: ListState<T>,
45 pub(crate) _phantom: PhantomData<T>,
46}
47
48#[derive(Default, PartialEq, Eq, Hash, IsVariant)]
49pub(crate) enum ListState<T> {
50 #[default]
51 Empty,
52 Full(ListContents<T>),
53}
54
55use ListState::*;
56
57pub(crate) struct ListContents<T> {
58 pub len: Length,
59 pub head: NodePtr<T>,
60 pub tail: NodePtr<T>,
61}
62
63impl<T> LinkedList<T> {
64 pub const fn new() -> LinkedList<T> {
66 LinkedList {
67 state: Empty,
68 _phantom: PhantomData,
69 }
70 }
71
72 pub const fn len(&self) -> usize {
74 self.state.len()
75 }
76
77 pub const fn is_empty(&self) -> bool {
79 self.state.is_empty()
80 }
81
82 pub const fn front(&self) -> Option<&T> {
84 match self.state {
85 Empty => None,
86 Full(ListContents { head, .. }) => Some(head.value()),
87 }
88 }
89
90 pub const fn front_mut(&mut self) -> Option<&mut T> {
92 match self.state {
93 Empty => None,
94 Full(ListContents { mut head, .. }) => Some(head.value_mut()),
95 }
96 }
97
98 pub const fn back(&self) -> Option<&T> {
100 match self.state {
101 Empty => None,
102 Full(ListContents { tail, .. }) => Some(tail.value()),
103 }
104 }
105
106 pub const fn back_mut(&mut self) -> Option<&mut T> {
108 match self.state {
109 Empty => None,
110 Full(ListContents { mut tail, .. }) => Some(tail.value_mut()),
111 }
112 }
113
114 pub fn push_front(&mut self, value: T) {
116 match &mut self.state {
117 Empty => self.state = ListState::single(value),
118 Full(contents) => contents.push_front(value),
119 }
120 }
121
122 pub fn push_back(&mut self, value: T) {
124 match &mut self.state {
125 Empty => self.state = ListState::single(value),
126 Full(contents) => contents.push_back(value),
127 }
128 }
129
130 pub fn pop_front(&mut self) -> Option<T> {
132 match &mut self.state {
133 Empty => None,
134 Full(ListContents { len, head, .. }) => {
135 let node = head.take_node();
136
137 match len.checked_sub(1) {
138 Some(new_len) => {
139 let new_head = unsafe { node.next.unwrap_unchecked() };
142 *head = new_head;
143 *new_head.prev_mut() = None;
144 *len = new_len;
145 },
146 None => self.state = Empty,
147 }
148
149 Some(node.value)
150 },
151 }
152 }
153
154 pub fn pop_back(&mut self) -> Option<T> {
156 match &mut self.state {
157 Empty => None,
158 Full(ListContents { len, tail, .. }) => {
159 let node = tail.take_node();
160
161 match len.checked_sub(1) {
162 Some(new_len) => {
163 let new_tail = unsafe { node.prev.unwrap_unchecked() };
166 *tail = new_tail;
167 *new_tail.next_mut() = None;
168 *len = new_len;
169 },
170 None => self.state = Empty,
171 }
172
173 Some(node.value)
174 },
175 }
176 }
177
178 pub fn get(&self, index: usize) -> &T {
185 self.try_get(index).throw()
186 }
187
188 pub fn try_get(&self, index: usize) -> Result<&T, IndexOutOfBounds> {
193 Ok(self.checked_seek(index)?.value())
194 }
195
196 pub fn get_mut(&mut self, index: usize) -> &mut T {
203 self.try_get_mut(index).throw()
204 }
205
206 pub fn try_get_mut(&mut self, index: usize) -> Result<&mut T, IndexOutOfBounds> {
211 Ok(self.checked_seek(index)?.value_mut())
212 }
213
214 pub fn insert(&mut self, index: usize, value: T) {
215 self.try_insert(index, value).throw()
216 }
217
218 pub fn try_insert(&mut self, index: usize, value: T) -> Result<(), IndexOutOfBounds> {
219 let contents = self.checked_contents_for_index_mut(index - 1)?;
220 match index {
221 0 => self.push_front(value),
222 val if val == contents.len.get() => self.push_back(value),
223 val => {
224 let prev_node = contents.seek(val - 1);
225
226 contents.len = contents.len.checked_add(1).ok_or(CapacityOverflow).throw();
227
228 let node = NodePtr::from_node(Node {
229 value,
230 prev: Some(prev_node),
231 next: *prev_node.next(),
232 });
233
234 unsafe { *prev_node.next().unwrap_unchecked().prev_mut() = Some(node); }
237 *prev_node.next_mut() = Some(node);
238 },
239 }
240 Ok(())
241 }
242
243 pub fn remove(&mut self, index: usize) -> T {
244 self.try_remove(index).throw()
245 }
246
247 pub fn try_remove(&mut self, index: usize) -> Result<T, IndexOutOfBounds> {
248 let contents = self.checked_contents_for_index_mut(index).throw();
249 match index {
250 0 => {
251 Ok(unsafe { self.pop_front().unwrap_unchecked() })
253 },
254 val if val == contents.last_index() => {
255 Ok(unsafe { self.pop_back().unwrap_unchecked() })
257 },
258 val => {
259 let node = contents.seek(val).take_node();
260
261 unsafe {
264 *node.prev.unwrap_unchecked().next_mut() = node.next;
265 *node.next.unwrap_unchecked().prev_mut() = node.prev;
266 }
267 contents.len = unsafe { contents.len.checked_sub(1).unwrap_unchecked() };
269
270 Ok(node.value)
271 },
272 }
273 }
274
275 pub fn replace(&mut self, index: usize, new_value: T) -> T {
276 self.try_replace(index, new_value).throw()
277 }
278
279 pub fn try_replace(&mut self, index: usize, new_value: T) -> Result<T, IndexOutOfBounds> {
280 Ok(mem::replace(
281 self.checked_seek(index)?.value_mut(),
282 new_value,
283 ))
284 }
285
286 pub fn append(&mut self, other: LinkedList<T>) {
287 match &mut self.state {
288 Empty => *self = other,
289 Full(self_contents) => match &other.state {
290 Empty => {},
291 Full(other_contents) => {
292 self_contents.len = self_contents.len
293 .checked_add(other_contents.len.get())
294 .ok_or(CapacityOverflow).throw();
295
296 *self_contents.tail.next_mut() = Some(other_contents.head);
297 *other_contents.head.prev_mut() = Some(self_contents.tail);
298 self_contents.tail = other_contents.tail;
299 },
300 },
301 }
302 }
303
304 pub fn cursor_head(mut self) -> Cursor<T> {
305 Cursor {
306 state: match mem::take(&mut self.state) {
307 Empty => CursorState::Empty,
308 Full(contents) => CursorState::Full(CursorContents {
309 pos: CursorPosition::Head,
310 list: contents,
311 }),
312 },
313 _phantom: PhantomData,
314 }
315 }
316
317 pub fn cursor_tail(mut self) -> Cursor<T> {
318 Cursor {
319 state: match mem::take(&mut self.state) {
320 Empty => CursorState::Empty,
321 Full(contents) => CursorState::Full(CursorContents {
322 pos: CursorPosition::Tail,
323 list: contents,
324 }),
325 },
326 _phantom: PhantomData,
327 }
328 }
329
330 pub fn cursor_front(mut self) -> Cursor<T> {
331 Cursor {
332 state: match mem::take(&mut self.state) {
333 Empty => CursorState::Empty,
334 Full(contents) => CursorState::Full(CursorContents {
335 pos: CursorPosition::Ptr {
336 ptr: contents.head,
337 index: 0,
338 },
339 list: contents,
340 }),
341 },
342 _phantom: PhantomData,
343 }
344 }
345
346 pub fn cursor_back(mut self) -> Cursor<T> {
347 Cursor {
348 state: match mem::take(&mut self.state) {
349 Empty => CursorState::Empty,
350 Full(contents) => CursorState::Full(CursorContents {
351 pos: CursorPosition::Ptr {
352 ptr: contents.tail,
353 index: contents.last_index(),
354 },
355 list: contents,
356 }),
357 },
358 _phantom: PhantomData,
359 }
360 }
361
362 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
363 self.into_iter()
364 }
365
366 pub fn iter(&self) -> Iter<'_, T> {
367 self.into_iter()
368 }
369}
370
371impl<T: Eq> LinkedList<T> {
372 pub fn index_of(&self, item: &T) -> Option<usize> {
373 for (index, element) in self.iter().enumerate() {
374 if element == item { return Some(index); }
375 }
376 None
377 }
378
379 pub fn contains(&self, item: &T) -> bool {
380 for i in self.iter() {
381 if i == item { return true; }
382 }
383 false
384 }
385}
386
387impl<T> LinkedList<T> {
388 pub(crate) fn checked_seek(&self, index: usize) -> Result<NodePtr<T>, IndexOutOfBounds> {
389 Ok(self.checked_contents_for_index(index)?.seek(index))
390 }
391
392 pub(crate) const fn checked_contents_for_index(
393 &self,
394 index: usize,
395 ) -> Result<&ListContents<T>, IndexOutOfBounds> {
396 match &self.state {
397 Empty => Err(IndexOutOfBounds { index, len: 0 }),
398 Full(contents) => {
399 let len = contents.len.get();
400 if index < len {
401 Ok(contents)
402 } else {
403 Err(IndexOutOfBounds { index, len })
404 }
405 },
406 }
407 }
408
409 pub(crate) const fn checked_contents_for_index_mut(
410 &mut self,
411 index: usize,
412 ) -> Result<&mut ListContents<T>, IndexOutOfBounds> {
413 match &mut self.state {
414 Empty => Err(IndexOutOfBounds { index, len: 0 }),
415 Full(contents) => {
416 let len = contents.len.get();
417 if index < len {
418 Ok(contents)
419 } else {
420 Err(IndexOutOfBounds { index, len })
421 }
422 },
423 }
424 }
425
426 #[allow(clippy::unwrap_used)]
427 pub(crate) fn verify_double_links(&self) {
428 match self.state {
429 Empty => {},
430 Full(ListContents { head, tail, .. }) => {
431 let mut curr = head;
432 while let Some(next) = curr.next() {
433 assert!(next.prev().unwrap() == curr);
435 curr = *next;
436 }
437 assert!(tail == curr);
438 },
439 }
440 }
441}
442
443impl<T> ListContents<T> {
444 pub fn seek(&self, index: usize) -> NodePtr<T> {
445 if index < self.len.get() / 2 {
446 self.seek_fwd(index, self.head)
447 } else {
448 self.seek_bwd(self.last_index() - index, self.tail)
449 }
450 }
451
452 pub fn seek_fwd(&self, count: usize, mut node: NodePtr<T>) -> NodePtr<T> {
453 for _ in 0..count {
454 node = node.next().unwrap();
455 }
456 node
457 }
458
459 pub fn seek_bwd(&self, count: usize, mut node: NodePtr<T>) -> NodePtr<T> {
460 for _ in 0..count {
461 node = node.prev().unwrap();
462 }
463 node
464 }
465
466 pub fn push_front(&mut self, value: T) {
467 self.len = self.len.checked_add(1).ok_or(CapacityOverflow).throw();
468
469 let node = NodePtr::from_node(Node {
470 value,
471 prev: None,
472 next: Some(self.head),
473 });
474
475 *self.head.prev_mut() = Some(node);
476 self.head = node;
477 }
478
479 pub fn push_back(&mut self, value: T) {
480 self.len = self.len.checked_add(1).ok_or(CapacityOverflow).throw();
481
482 let node = NodePtr::from_node(Node {
483 value,
484 prev: Some(self.tail),
485 next: None,
486 });
487
488 *self.tail.next_mut() = Some(node);
489 self.tail = node;
490 }
491
492 pub fn wrap_one(value: T) -> ListContents<T> {
493 let node = NodePtr::from_node(Node {
494 value,
495 prev: None,
496 next: None,
497 });
498
499 ListContents {
500 len: ONE,
501 head: node,
502 tail: node,
503 }
504 }
505
506 pub const fn last_index(&self) -> usize {
507 self.len.get() - 1
508 }
509}
510
511impl<T> ListState<T> {
512 pub fn single(value: T) -> ListState<T> {
513 Full(ListContents::wrap_one(value))
514 }
515}
516
517impl<T> Index<usize> for LinkedList<T> {
518 type Output = T;
519
520 fn index(&self, index: usize) -> &Self::Output {
521 self.get(index)
522 }
523}
524
525impl<T> IndexMut<usize> for LinkedList<T> {
526 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
527 self.get_mut(index)
528 }
529}
530
531impl<T> FromIterator<T> for LinkedList<T> {
532 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
533 let mut list = LinkedList::new();
534 for item in iter.into_iter() {
535 list.push_back(item);
536 }
537 list
538 }
539}
540
541impl<T> Default for LinkedList<T> {
542 fn default() -> Self {
543 Self::new()
544 }
545}
546
547impl<T> Drop for LinkedList<T> {
548 fn drop(&mut self) {
549 match self.state {
550 Empty => {},
551 Full(ListContents { head, .. }) => {
552 let mut curr = Some(head);
553 while let Some(ptr) = curr {
554 curr = *ptr.next();
555 unsafe { ptr.drop_node(); }
556 }
557 },
558 }
559 }
560}
561
562impl<T: PartialEq> PartialEq for ListContents<T> {
563 fn eq(&self, other: &Self) -> bool {
564 if self.len != other.len { return false; }
565 let mut node_a = self.head;
566 let mut node_b = other.head;
567
568 loop {
569 if node_a.value() != node_b.value() {
570 break false;
571 }
572 match (node_a.next(), node_b.next()) {
573 (Some(next_a), Some(next_b)) => {
574 node_a = *next_a;
575 node_b = *next_b;
576 },
577 _ => break true,
580 }
581 }
582 }
583}
584
585impl<T: Eq> Eq for ListContents<T> {}
586
587impl<T: Hash> Hash for ListContents<T> {
588 fn hash<H: Hasher>(&self, state: &mut H) {
589 self.len.hash(state);
590 let mut node = self.head;
591
592 loop {
593 node.value().hash(state);
594 match node.next() {
595 Some(next) => {
596 node = *next;
597 },
598 _ => break,
599 }
600 }
601
602 0xFF.hash(state);
604 }
605}
606
607impl<T> Clone for ListContents<T> {
608 fn clone(&self) -> Self {
609 ListContents {
610 len: self.len,
611 head: self.head,
612 tail: self.tail,
613 }
614 }
615}
616
617impl<T> ListState<T> {
618 pub const fn len(&self) -> usize {
619 match self {
620 Empty => 0,
621 Full(ListContents { len, .. }) => len.get(),
622 }
623 }
624}
625
626impl<T> Clone for ListState<T> {
627 fn clone(&self) -> Self {
628 match self {
629 Empty => Empty,
630 Full(contents) => Full(contents.clone()),
631 }
632 }
633}
634
635impl<T: Debug> Debug for LinkedList<T> {
636 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
637 f.debug_struct("LinkedList")
638 .field_with("contents", |f| f.debug_list().entries(self.iter()).finish())
639 .field("len", &self.len())
640 .finish()
641 }
642}
643
644impl<T: Debug> Display for LinkedList<T> {
645 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
646 write!(
647 f,
648 "({})",
649 self.iter()
650 .map(|i| format!("{i:?}"))
651 .collect::<Vector<String>>()
652 .join(") -> (")
653 )
654 }
655}