orx_selfref_col/references/
vec.rs

1use super::{NodePtr, refs::Refs};
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 the node pointers as a slice.
68    pub fn as_slice(&self) -> &[NodePtr<V>] {
69        self.0.as_slice()
70    }
71
72    /// Returns true if the number of references is zero.
73    pub fn is_empty(&self) -> bool {
74        self.0.is_empty()
75    }
76
77    /// Returns the i-th node pointer; None if out of bounds.
78    pub fn get(&self, i: usize) -> Option<&NodePtr<V>> {
79        self.0.get(i)
80    }
81
82    /// Creates an iterator over node pointers of the references collection.
83    pub fn iter(&self) -> core::slice::Iter<'_, NodePtr<V>> {
84        self.0.iter()
85    }
86
87    /// Creates a mutable iterator over node pointers of the references collection.
88    pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, NodePtr<V>> {
89        self.0.iter_mut()
90    }
91
92    /// Pushes the node references to the end of the references collection.
93    pub fn push(&mut self, node_ptr: NodePtr<V>) {
94        self.0.push(node_ptr);
95    }
96
97    /// Inserts the reference with the given `node_ptr` to the given `position` of the references collection.
98    pub fn insert(&mut self, position: usize, node_ptr: NodePtr<V>) {
99        self.0.insert(position, node_ptr);
100    }
101
102    /// Inserts the reference with the given `node_ptr` just before the given `pivot_ptr` the reference if it exists;
103    /// and returns the position that the new reference is inserted to.
104    ///
105    /// Does nothing leaving the children unchanged if the `pivot_ptr` reference does not exists, and returns None.
106    pub fn push_before(&mut self, pivot_ptr: &NodePtr<V>, node_ptr: NodePtr<V>) -> Option<usize> {
107        let position = self.iter().position(|x| x == pivot_ptr);
108        if let Some(p) = position {
109            self.0.insert(p, node_ptr);
110        }
111        position
112    }
113
114    /// Inserts the reference with the given `node_ptr` just after the given `pivot_ptr` the reference if it exists;
115    /// and returns the position that the new reference is inserted to.
116    ///
117    /// Does nothing leaving the children unchanged if the `pivot_ptr` reference does not exists, and returns None.
118    pub fn push_after(&mut self, pivot_ptr: &NodePtr<V>, node_ptr: NodePtr<V>) -> Option<usize> {
119        let position = self.iter().position(|x| x == pivot_ptr);
120        if let Some(p) = position {
121            self.0.insert(p + 1, node_ptr);
122        }
123        position
124    }
125
126    /// Replaces the node reference `old_node_ptr` with the `new_node_ptr` and returns
127    /// the position of the reference.
128    ///
129    /// Does nothing and returns None if the `old_node_ptr` is absent.
130    pub fn replace_with(
131        &mut self,
132        old_node_ptr: &NodePtr<V>,
133        new_node_ptr: NodePtr<V>,
134    ) -> Option<usize> {
135        let position = self.0.iter().position(|x| x == old_node_ptr);
136        if let Some(p) = position {
137            self.0[p] = new_node_ptr;
138        }
139        position
140    }
141}