]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_ast_pretty/src/pp/ring.rs
Auto merge of #93933 - matthiaskrgr:rollup-1hjae6g, r=matthiaskrgr
[rust.git] / compiler / rustc_ast_pretty / src / pp / ring.rs
1 use std::collections::VecDeque;
2 use std::ops::{Index, IndexMut};
3
4 /// A view onto a finite range of an infinitely long sequence of T.
5 ///
6 /// The Ts are indexed 0..infinity. A RingBuffer begins as a view of elements
7 /// 0..0 (i.e. nothing). The user of the RingBuffer advances its left and right
8 /// position independently, although only in the positive direction, and only
9 /// with left <= right at all times.
10 ///
11 /// Holding a RingBuffer whose view is elements left..right gives the ability to
12 /// use Index and IndexMut to access elements i in the infinitely long queue for
13 /// which left <= i < right.
14 pub struct RingBuffer<T> {
15     data: VecDeque<T>,
16     // Abstract index of data[0] in the infinitely sized queue.
17     offset: usize,
18 }
19
20 impl<T> RingBuffer<T> {
21     pub fn new() -> Self {
22         RingBuffer { data: VecDeque::new(), offset: 0 }
23     }
24
25     pub fn is_empty(&self) -> bool {
26         self.data.is_empty()
27     }
28
29     pub fn push(&mut self, value: T) -> usize {
30         let index = self.offset + self.data.len();
31         self.data.push_back(value);
32         index
33     }
34
35     pub fn clear(&mut self) {
36         self.data.clear();
37     }
38
39     pub fn index_of_first(&self) -> usize {
40         self.offset
41     }
42
43     pub fn first(&self) -> Option<&T> {
44         self.data.front()
45     }
46
47     pub fn first_mut(&mut self) -> Option<&mut T> {
48         self.data.front_mut()
49     }
50
51     pub fn pop_first(&mut self) -> Option<T> {
52         let first = self.data.pop_front()?;
53         self.offset += 1;
54         Some(first)
55     }
56
57     pub fn last(&self) -> Option<&T> {
58         self.data.back()
59     }
60
61     pub fn last_mut(&mut self) -> Option<&mut T> {
62         self.data.back_mut()
63     }
64 }
65
66 impl<T> Index<usize> for RingBuffer<T> {
67     type Output = T;
68     fn index(&self, index: usize) -> &Self::Output {
69         &self.data[index.checked_sub(self.offset).unwrap()]
70     }
71 }
72
73 impl<T> IndexMut<usize> for RingBuffer<T> {
74     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
75         &mut self.data[index.checked_sub(self.offset).unwrap()]
76     }
77 }