orx_selfref_col/references/
array_left_most.rs1use super::{
2 NodePtr,
3 iter::{ArrayLeftMostPtrIter, ArrayLeftMostPtrIterMut},
4 refs::Refs,
5};
6use crate::variant::Variant;
7use core::fmt::Debug;
8
9pub struct RefsArrayLeftMost<const N: usize, V>
16where
17 V: Variant,
18{
19 array: [Option<NodePtr<V>>; N],
20 len: usize,
21}
22
23impl<const N: usize, V: Variant> Clone for RefsArrayLeftMost<N, V> {
24 fn clone(&self) -> Self {
25 Self {
26 array: self.array.clone(),
27 len: self.len,
28 }
29 }
30}
31
32impl<const N: usize, V: Variant> Debug for RefsArrayLeftMost<N, V> {
33 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
34 f.debug_tuple("RefsArrayLeftMost")
35 .field(&self.array)
36 .finish()
37 }
38}
39
40impl<const N: usize, V> Refs for RefsArrayLeftMost<N, V>
41where
42 V: Variant,
43{
44 #[inline(always)]
45 fn empty() -> Self {
46 Self {
47 array: [const { None }; N],
48 len: 0,
49 }
50 }
51
52 #[inline(always)]
53 fn is_empty(&self) -> bool {
54 self.len == 0
55 }
56
57 #[inline(always)]
58 fn clear(&mut self) {
59 self.array
60 .iter_mut()
61 .take(self.len)
62 .for_each(|x| _ = x.take());
63 self.len = 0;
64 }
65
66 #[inline(always)]
67 fn remove_at(&mut self, ref_idx: usize) {
68 self.array[ref_idx] = None;
69 for i in (ref_idx + 1)..self.len {
70 self.array[i - 1] = self.array[i].take();
71 }
72 self.len -= 1;
73 }
74
75 #[inline(always)]
76 fn remove(&mut self, ptr: usize) -> Option<usize> {
77 let x = self.array.iter().enumerate().find(|x| match x.1 {
78 Some(x) => x.ptr() as usize == ptr,
79 None => false,
80 });
81 match x {
82 Some((ref_idx, _)) => {
83 self.remove_at(ref_idx);
84 Some(ref_idx)
85 }
86 None => None,
87 }
88 }
89}
90
91impl<const N: usize, V: Variant> RefsArrayLeftMost<N, V> {
92 pub fn len(&self) -> usize {
94 self.len
95 }
96
97 pub fn is_empty(&self) -> bool {
99 self.len == 0
100 }
101
102 pub fn get(&self, ref_idx: usize) -> Option<&NodePtr<V>> {
104 match ref_idx < N {
105 true => self.array[ref_idx].as_ref(),
106 false => None,
107 }
108 }
109
110 pub fn as_slice(&self) -> &[Option<NodePtr<V>>] {
115 &self.array[..self.len]
116 }
117
118 pub fn iter(&self) -> ArrayLeftMostPtrIter<'_, V> {
120 let slice = &self.array[..self.len];
121 ArrayLeftMostPtrIter::new(slice.iter())
122 }
123
124 pub fn iter_mut(&mut self) -> ArrayLeftMostPtrIterMut<'_, V> {
126 let slice = &mut self.array[..self.len];
127 ArrayLeftMostPtrIterMut::new(slice.iter_mut())
128 }
129
130 pub fn has_room(&self) -> bool {
132 self.len < N
133 }
134
135 pub fn push(&mut self, node_ptr: NodePtr<V>) {
141 self.assert_has_room_for::<1>();
142 self.array[self.len] = Some(node_ptr);
143 self.len += 1;
144 }
145
146 pub fn insert(&mut self, position: usize, node_ptr: NodePtr<V>) {
148 for q in (position..self.len).rev() {
149 self.array[q + 1] = self.array[q].clone();
150 }
151 self.array[position] = Some(node_ptr);
152 self.len += 1;
153 }
154
155 pub fn push_before(&mut self, pivot_ptr: &NodePtr<V>, node_ptr: NodePtr<V>) -> Option<usize> {
160 self.assert_has_room_for::<1>();
161 let position = self.iter().position(|x| x == pivot_ptr);
162 if let Some(p) = position {
163 self.insert(p, node_ptr);
164 }
165 position
166 }
167
168 pub fn push_after(&mut self, pivot_ptr: &NodePtr<V>, node_ptr: NodePtr<V>) -> Option<usize> {
173 self.assert_has_room_for::<1>();
174 let position = self.iter().position(|x| x == pivot_ptr);
175 if let Some(p) = position {
176 self.insert(p + 1, node_ptr);
177 }
178 position
179 }
180
181 pub fn replace_with(
186 &mut self,
187 old_node_ptr: &NodePtr<V>,
188 new_node_ptr: NodePtr<V>,
189 ) -> Option<usize> {
190 let position = self.iter().position(|x| x == old_node_ptr);
191 if let Some(p) = position {
192 self.array[p] = Some(new_node_ptr);
193 }
194 position
195 }
196
197 fn assert_has_room_for<const P: usize>(&self) {
199 assert!(
200 self.len + P <= N,
201 "Pushing the {}-th reference to array-backed references with maximum of {} elements.",
202 N + P,
203 N
204 );
205 }
206}