Skip to main content

vector_growing/
lib.rs

1//    Copyright 2024 Dmitriy Mayorov
2
3//    Licensed under the Apache License, Version 2.0 (the "License");
4//    you may not use this file except in compliance with the License.
5//    You may obtain a copy of the License at
6
7//        http://www.apache.org/licenses/LICENSE-2.0
8
9//    Unless required by applicable law or agreed to in writing, software
10//    distributed under the License is distributed on an "AS IS" BASIS,
11//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//    See the License for the specific language governing permissions and
13//    limitations under the License.
14
15use std::ops::{Index, IndexMut};
16mod iter;
17use iter::*;
18
19/// It is similar to a regular `Vec`, with one exception -
20/// the size is not reduced. `VecGrow` can constantly grow,
21/// but not decrease, and when objects are deleted,
22/// their place remains for the new object as a free index,
23/// which eases the memory power in the case of permanent
24/// deletion and creation of objects.
25/// # Examples
26/// ``` rust
27/// use vector_growing::*;
28///
29/// let mut vg = VecGrow::new();
30/// vg.push(1);
31/// vg.push(2);
32///
33/// assert_eq!(vg[0], Some(1));
34/// assert_eq!(vg[1], Some(2));
35///
36/// vg.remove(0);
37///
38/// assert_eq!(vg[0], None);
39///
40/// vg.push(1);
41///
42/// assert_eq!(vg[0], Some(1));
43/// ```
44/// Initializing VecGrow using a macro:
45/// ``` rust
46/// use vector_growing::*;
47///
48/// let vg_empty: VecGrow<u8> = vec_grow![];
49/// let vg_num = vec_grow![1, 2, 3];
50/// let vg_zero = vec_grow![0; 100];
51///
52/// assert!(vg_empty.is_empty());
53/// assert_eq!(vg_num[1], Some(2));
54/// assert_eq!(vg_zero[99], Some(0));
55/// ```
56#[derive(Debug, Clone)]
57pub struct VecGrow<T> {
58    free_idxs: Vec<usize>,
59    objects: Vec<Option<T>>,
60}
61
62impl<T> VecGrow<T> {
63    /// Create of `VecGrow`
64    ///
65    /// # Examples
66    /// ``` rust
67    /// use vector_growing::*;
68    /// let _vg: VecGrow<u8> = VecGrow::new();
69    /// // or
70    /// let _vg: VecGrow<u8> = vec_grow!();
71    /// let _vg = vec_grow!(0);
72    /// let _vg = vec_grow!(0; 100);
73    /// let _vg = vec_grow!(1, 2, 3);
74    /// ```
75    pub fn new() -> Self {
76        Self {
77            free_idxs: vec![],
78            objects: vec![],
79        }
80    }
81
82    /// Adding a new element to the place of the old one,
83    /// if there is no free space, selected a new place and add the element.
84    pub fn push(&mut self, value: T) {
85        if let Some(last_index) = self.free_idxs.last() {
86            self.objects[*last_index] = Some(value);
87            self.free_idxs.remove(*last_index);
88        } else {
89            self.objects.push(Some(value));
90        }
91    }
92
93    /// Deleting an object and memorize the vacant index.
94    pub fn remove(&mut self, index: usize) {
95        fn assert_failed(index: usize, len: usize) -> ! {
96            panic!("removal index (is {index}) should be < len (is {len})");
97        }
98
99        if index >= self.objects.len() {
100            assert_failed(index, self.objects.len());
101        }
102
103        self.free_idxs.push(index);
104        self[index] = None;
105    }
106
107    /// The count of real objects excluding free cells.
108    pub fn count(&self) -> usize {
109        self.objects.len() - self.free_idxs.len()
110    }
111
112    /// The length of the object vector
113    pub fn len(&self) -> usize {
114        self.objects.len()
115    }
116
117    /// Creating an immutable iterator.
118    /// # Examples
119    /// ``` rust
120    /// use vector_growing::*;
121    /// let vg = vec_grow!(1, 2, 3);
122    /// let mut vg_iter = vg.iter();
123    ///
124    /// assert_eq!(vg_iter.next(), Some(&1));
125    /// assert_eq!(vg_iter.next(), Some(&2));
126    /// assert_eq!(vg_iter.next(), Some(&3));
127    /// ```
128    pub fn iter(&self) -> Iter<'_, T> {
129        Iter::new(self)
130    }
131
132    /// Creating an mutable iterator.
133    /// # Examples
134    /// ``` rust
135    /// use vector_growing::*;
136    ///
137    /// let mut vg = vec_grow!(1, 2, 3);
138    ///
139    /// for num in vg.iter_mut() {
140    ///     *num += 1;
141    /// }
142    ///
143    /// let mut vg_iter = vg.iter();
144    /// assert_eq!(vg_iter.next(), Some(&2));
145    /// assert_eq!(vg_iter.next(), Some(&3));
146    /// assert_eq!(vg_iter.next(), Some(&4));
147    /// ```
148    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
149        IterMut::new(self)
150    }
151
152    pub fn is_empty(&self) -> bool {
153        self.free_idxs.len() == self.len()
154    }
155}
156
157impl<T> Index<usize> for VecGrow<T> {
158    type Output = Option<T>;
159    fn index(&self, index: usize) -> &Self::Output {
160        &self.objects[index]
161    }
162}
163
164impl<T> IndexMut<usize> for VecGrow<T> {
165    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
166        &mut self.objects[index]
167    }
168}
169
170#[macro_export]
171macro_rules! vec_grow {
172    [] => {
173        VecGrow::new()
174    };
175
176    [$($v:expr),*] => {
177        {
178            let mut vg = VecGrow::new();
179            $(
180                vg.push($v);
181            )*
182
183            vg
184        }
185    };
186
187    [$value:expr; $count:expr] => {
188        {
189            let mut vg = VecGrow::new();
190            for _ in 0..$count {
191                vg.push($value);
192            }
193
194            vg
195        }
196    }
197}