orx_selfref_col/references/
vec.rs

1use super::{refs::Refs, NodePtr};
2use crate::Variant;
3use alloc::vec::Vec;
4use core::fmt::Debug;
5
6/// A dynamic number of references.
7pub struct RefsVec<V>(Vec<NodePtr<V>>)
8where
9    V: Variant;
10
11impl<V: Variant> Clone for RefsVec<V> {
12    fn clone(&self) -> Self {
13        Self(self.0.clone())
14    }
15}
16
17impl<V: Variant> Debug for RefsVec<V> {
18    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19        f.debug_tuple("RefsVec").field(&self.0).finish()
20    }
21}
22
23impl<V: Variant> Refs for RefsVec<V> {
24    #[inline(always)]
25    fn empty() -> Self {
26        Self(Vec::new())
27    }
28
29    #[inline(always)]
30    fn is_empty(&self) -> bool {
31        self.0.is_empty()
32    }
33
34    #[inline(always)]
35    fn clear(&mut self) {
36        self.0.clear();
37    }
38
39    #[inline(always)]
40    fn remove_at(&mut self, ref_idx: usize) {
41        self.0.remove(ref_idx);
42    }
43
44    #[inline(always)]
45    fn remove(&mut self, ptr: usize) -> Option<usize> {
46        let x = self
47            .0
48            .iter()
49            .enumerate()
50            .find(|x| x.1.ptr() as usize == ptr);
51        match x {
52            Some((ref_idx, _)) => {
53                self.0.remove(ref_idx);
54                Some(ref_idx)
55            }
56            None => None,
57        }
58    }
59}
60
61impl<V: Variant> RefsVec<V> {
62    /// Returns the number of references.
63    pub fn len(&self) -> usize {
64        self.0.len()
65    }
66
67    /// Returns true if the number of references is zero.
68    pub fn is_empty(&self) -> bool {
69        self.0.is_empty()
70    }
71
72    /// Returns the i-th node pointer; None if out of bounds.
73    pub fn get(&self, i: usize) -> Option<&NodePtr<V>> {
74        self.0.get(i)
75    }
76
77    /// Creates an iterator over node pointers of the references collection.
78    pub fn iter(&self) -> core::slice::Iter<NodePtr<V>> {
79        self.0.iter()
80    }
81
82    /// Creates a mutable iterator over node pointers of the references collection.
83    pub fn iter_mut(&mut self) -> core::slice::IterMut<NodePtr<V>> {
84        self.0.iter_mut()
85    }
86
87    /// Pushes the node references to the end of the references collection.
88    pub fn push(&mut self, node_ptr: NodePtr<V>) {
89        self.0.push(node_ptr);
90    }
91
92    /// Inserts the reference with the given `node_ptr` to the given `position` of the references collection.
93    pub fn insert(&mut self, position: usize, node_ptr: NodePtr<V>) {
94        self.0.insert(position, node_ptr);
95    }
96
97    /// Inserts the reference with the given `node_ptr` just before the given `pivot_ptr` the reference if it exists;
98    /// and returns the position that the new reference is inserted to.
99    ///
100    /// Does nothing leaving the children unchanged if the `pivot_ptr` reference does not exists, and returns None.
101    pub fn push_before(&mut self, pivot_ptr: &NodePtr<V>, node_ptr: NodePtr<V>) -> Option<usize> {
102        let position = self.iter().position(|x| x == pivot_ptr);
103        if let Some(p) = position {
104            self.0.insert(p, node_ptr);
105        }
106        position
107    }
108
109    /// Inserts the reference with the given `node_ptr` just after the given `pivot_ptr` the reference if it exists;
110    /// and returns the position that the new reference is inserted to.
111    ///
112    /// Does nothing leaving the children unchanged if the `pivot_ptr` reference does not exists, and returns None.
113    pub fn push_after(&mut self, pivot_ptr: &NodePtr<V>, node_ptr: NodePtr<V>) -> Option<usize> {
114        let position = self.iter().position(|x| x == pivot_ptr);
115        if let Some(p) = position {
116            self.0.insert(p + 1, node_ptr);
117        }
118        position
119    }
120
121    /// Replaces the node reference `old_node_ptr` with the `new_node_ptr` and returns
122    /// the position of the reference.
123    ///
124    /// Does nothing and returns None if the `old_node_ptr` is absent.
125    pub fn replace_with(
126        &mut self,
127        old_node_ptr: &NodePtr<V>,
128        new_node_ptr: NodePtr<V>,
129    ) -> Option<usize> {
130        let position = self.0.iter().position(|x| x == old_node_ptr);
131        if let Some(p) = position {
132            self.0[p] = new_node_ptr;
133        }
134        position
135    }
136}