my_ecs/ds/vec/
dedup_vec.rs

1use std::{fmt, hash};
2
3/// A trait for [`DedupVec`].
4///
5/// This trait provides common interfaces for `DedupVec`.
6pub trait AsDedupVec {
7    /// Vector item type.
8    type Item;
9
10    /// Vector type.
11    type Container;
12
13    /// Creates a new empty vector.
14    fn new() -> Self;
15
16    /// Returns number of items.
17    fn len(&self) -> usize;
18
19    /// Returns true if the vector is empty.
20    fn is_empty(&self) -> bool {
21        self.len() == 0
22    }
23
24    /// Returns true if the vector contains the given value.
25    fn contains(&self, value: &Self::Item) -> bool;
26
27    /// Appends the given value to the end of the vector.
28    fn push(&mut self, value: Self::Item);
29
30    /// Removes an item that is equal to the given value from the vector.
31    fn remove(&mut self, value: &Self::Item) -> Option<Self::Item>;
32
33    /// Extends the vector with the given iterator.
34    fn extend(&mut self, iter: impl IntoIterator<Item = Self::Item>);
35
36    /// Returns an iterator visiting all items in the vector.
37    fn iter(&self) -> impl Iterator<Item = &Self::Item>;
38}
39
40// ON = true means deduplication is activated. In this case, we keep the vector
41// deduplicated whenever insertion or removal occurs.
42impl<T> AsDedupVec for DedupVec<T, true>
43where
44    T: Ord,
45{
46    type Item = T;
47    type Container = Vec<T>;
48
49    /// Creates a new empty vector.
50    ///
51    /// The vector will automatically sort and deduplicate items for you due to
52    /// `ON = true`.
53    ///
54    /// # Examples
55    ///
56    /// ```
57    /// use my_ecs::ds::{AsDedupVec, DedupVec};
58    ///
59    /// let mut v = DedupVec::<i32, true>::new();
60    /// ```
61    fn new() -> Self {
62        DedupVec { inner: Vec::new() }
63    }
64
65    /// Returns number of items.
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// use my_ecs::ds::{AsDedupVec, DedupVec};
71    ///
72    /// let mut v = DedupVec::<_, true>::new();
73    /// v.push(0);
74    /// assert_eq!(v.len(), 1);
75    /// ```
76    fn len(&self) -> usize {
77        self.inner.len()
78    }
79
80    /// Returns true if the vector contains the given value.
81    ///
82    /// # Examples
83    ///
84    /// ```
85    /// use my_ecs::ds::{AsDedupVec, DedupVec};
86    ///
87    /// let mut v = DedupVec::<_, true>::new();
88    /// v.push(0);
89    /// assert!(v.contains(&0));
90    /// ```
91    fn contains(&self, value: &Self::Item) -> bool {
92        self.inner.binary_search(value).is_ok()
93    }
94
95    /// Appends the given value to the end of the vector.
96    ///
97    /// The vector will automatically sort and deduplicate items for you due to
98    /// `ON = true`.
99    ///
100    /// # Examples
101    ///
102    /// ```
103    /// use my_ecs::ds::{AsDedupVec, DedupVec};
104    ///
105    /// let mut v = DedupVec::<_, true>::new();
106    /// v.push(0);
107    /// v.push(0);
108    /// v.push(2);
109    /// v.push(1);
110    /// let dedup = v.iter().cloned().collect::<Vec<_>>();
111    /// assert_eq!(dedup, [0, 1, 2]);
112    /// ```
113    fn push(&mut self, value: Self::Item) {
114        if let Err(i) = self.inner.binary_search(&value) {
115            self.inner.insert(i, value);
116        }
117    }
118
119    /// Removes an item that is equal to the given value from the vector.
120    ///
121    /// The vector will automatically sort and deduplicate items for you due to
122    /// `ON = true`.
123    ///
124    /// # Examples
125    ///
126    /// ```
127    /// use my_ecs::ds::{AsDedupVec, DedupVec};
128    ///
129    /// let mut v = DedupVec::<_, true>::new();
130    /// v.push(0);
131    /// v.push(2);
132    /// v.push(1);
133    /// v.remove(&1);
134    /// let dedup = v.iter().cloned().collect::<Vec<_>>();
135    /// assert_eq!(dedup, [0, 2]);
136    /// ```
137    fn remove(&mut self, value: &Self::Item) -> Option<Self::Item> {
138        if let Ok(i) = self.inner.binary_search(value) {
139            Some(self.inner.remove(i))
140        } else {
141            None
142        }
143    }
144
145    /// Extends the vector with the given iterator.
146    ///
147    /// The vector will automatically sort and deduplicate items for you due to
148    /// `ON = true`.
149    ///
150    /// # Examples
151    ///
152    /// ```
153    /// use my_ecs::ds::{AsDedupVec, DedupVec};
154    ///
155    /// let mut v = DedupVec::<_, true>::new();
156    /// v.extend([0, 2, 1]);
157    /// let dedup = v.iter().cloned().collect::<Vec<_>>();
158    /// assert_eq!(dedup, [0, 1, 2]);
159    /// ```
160    fn extend(&mut self, iter: impl IntoIterator<Item = Self::Item>) {
161        self.inner.extend(iter);
162        self.inner.sort_unstable();
163        self.inner.dedup();
164    }
165
166    /// Returns an iterator visiting all items in the vector.
167    ///
168    /// # Examples
169    ///
170    /// ```
171    /// use my_ecs::ds::{AsDedupVec, DedupVec};
172    ///
173    /// let mut v = DedupVec::<_, true>::new();
174    /// v.push(0);
175    /// v.push(1);
176    /// for x in v.iter() {
177    ///     println!("{x}");
178    /// }
179    /// ```
180    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
181        self.inner.iter()
182    }
183}
184
185// ON = false means deduplication is not activated.
186// In release mode, we don't check duplication at all.
187// Clients have responsibility for keeping deduplicated state.
188#[cfg(not(debug_assertions))]
189impl<T> AsDedupVec for DedupVec<T, false>
190where
191    T: hash::Hash + Eq + Clone,
192{
193    type Item = T;
194    type Container = Vec<T>;
195
196    fn new() -> Self {
197        Self { inner: Vec::new() }
198    }
199
200    fn len(&self) -> usize {
201        self.inner.len()
202    }
203
204    fn contains(&self, value: &Self::Item) -> bool {
205        self.inner.iter().any(|v| v == value)
206    }
207
208    fn push(&mut self, value: Self::Item) {
209        self.inner.push(value);
210    }
211
212    fn remove(&mut self, value: &Self::Item) -> Option<Self::Item> {
213        if let Some((i, _)) = self.inner.iter().enumerate().find(|(_, x)| *x == value) {
214            Some(self.inner.swap_remove(i))
215        } else {
216            None
217        }
218    }
219
220    fn extend(&mut self, iter: impl IntoIterator<Item = Self::Item>) {
221        self.inner.extend(iter);
222    }
223
224    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
225        self.inner.iter()
226    }
227}
228
229// ON = false means deduplication is not activated. However, in debug mode,
230// panics if the container gets duplicate items in it.
231#[cfg(debug_assertions)]
232impl<T> AsDedupVec for DedupVec<T, false>
233where
234    T: hash::Hash + Eq + Default + Clone,
235{
236    type Item = T;
237    type Container = crate::ds::list::SetValueList<T, crate::DefaultRandomState>;
238
239    /// Creates a new empty vector.
240    ///
241    /// The vector won't do anything to keep the deduplicated status, but it
242    /// panics when you insert duplicate item into the vector in debug mode due
243    /// to `ON = false`.
244    ///
245    /// # Examples
246    ///
247    /// ```
248    /// use my_ecs::ds::{AsDedupVec, DedupVec};
249    ///
250    /// let mut v = DedupVec::<i32, false>::new();
251    /// ```
252    fn new() -> Self {
253        Self {
254            inner: crate::ds::list::SetValueList::default(),
255        }
256    }
257
258    /// Returns number of items.
259    ///
260    /// # Examples
261    ///
262    /// ```
263    /// use my_ecs::ds::{AsDedupVec, DedupVec};
264    ///
265    /// let mut v = DedupVec::<_, false>::new();
266    /// v.push(0);
267    /// assert_eq!(v.len(), 1);
268    /// ```
269    fn len(&self) -> usize {
270        self.inner.len()
271    }
272
273    /// Returns true if the vector contains the given value.
274    ///
275    /// # Examples
276    ///
277    /// ```
278    /// use my_ecs::ds::{AsDedupVec, DedupVec};
279    ///
280    /// let mut v = DedupVec::<_, false>::new();
281    /// v.push(0);
282    /// assert!(v.contains(&0));
283    /// ```
284    fn contains(&self, value: &Self::Item) -> bool {
285        self.inner.contains_key(value)
286    }
287
288    /// Appends the given value to the end of the vector.
289    ///
290    /// The vector won't do anything to keep the deduplicated status, but it
291    /// panics when you insert duplicate item into the vector in debug mode due
292    /// to `ON = false`.
293    ///
294    /// # Examples
295    ///
296    /// ```
297    /// use my_ecs::ds::{AsDedupVec, DedupVec};
298    ///
299    /// let mut v = DedupVec::<_, false>::new();
300    /// v.push(0);
301    /// v.push(2);
302    /// v.push(1);
303    /// let dedup = v.iter().cloned().collect::<Vec<_>>();
304    /// assert_eq!(dedup, [0, 2, 1]);
305    /// ```
306    fn push(&mut self, value: Self::Item) {
307        assert!(!self.contains(&value), "duplicate item detected",);
308
309        self.inner.push_back(value);
310    }
311
312    /// Removes an item that is equal to the given value from the vector.
313    ///
314    /// The vector won't do anything to keep the deduplicated status, but it
315    /// panics when you insert duplicate item into the vector in debug mode due
316    /// to `ON = false`.
317    ///
318    /// # Examples
319    ///
320    /// ```
321    /// use my_ecs::ds::{AsDedupVec, DedupVec};
322    ///
323    /// let mut v = DedupVec::<_, false>::new();
324    /// v.push(0);
325    /// v.push(1);
326    /// v.push(2);
327    /// v.remove(&1);
328    /// let dedup = v.iter().cloned().collect::<Vec<_>>();
329    /// assert_eq!(dedup, [0, 2]);
330    /// ```
331    fn remove(&mut self, value: &Self::Item) -> Option<Self::Item> {
332        self.inner.remove(value)
333    }
334
335    /// Extends the vector with the given iterator.
336    ///
337    /// The vector won't do anything to keep the deduplicated status, but it
338    /// panics when you insert duplicate item into the vector in debug mode due
339    /// to `ON = false`.
340    ///
341    /// # Examples
342    ///
343    /// ```
344    /// use my_ecs::ds::{AsDedupVec, DedupVec};
345    ///
346    /// let mut v = DedupVec::<_, false>::new();
347    /// v.extend([0, 2, 1]);
348    /// let dedup = v.iter().cloned().collect::<Vec<_>>();
349    /// assert_eq!(dedup, [0, 2, 1]);
350    /// ```
351    fn extend(&mut self, iter: impl IntoIterator<Item = Self::Item>) {
352        for value in iter {
353            self.push(value);
354        }
355    }
356
357    /// Returns an iterator visiting all items in the vector.
358    ///
359    /// # Examples
360    ///
361    /// ```
362    /// use my_ecs::ds::{AsDedupVec, DedupVec};
363    ///
364    /// let mut v = DedupVec::<_, false>::new();
365    /// v.push(0);
366    /// v.push(1);
367    /// for x in v.iter() {
368    ///     println!("{x}");
369    /// }
370    /// ```
371    fn iter(&self) -> impl Iterator<Item = &Self::Item> {
372        self.inner.values()
373    }
374}
375
376/// Deduplicated vector.
377///
378/// - If ON is true, then the vector keeps *sorted* and *deduplicated* status.
379///   It means the vector will conduct sorting and binary search whenever you
380///   insert or remove items into or from the vector. In this case, [`Vec`] is
381///   used as data container.
382///
383/// - If ON is false, on the other hand, the vector acts differently according
384///   to build mode.
385///   * *debug mode* : Vector will panic when duplication detected.
386///     [`SetValueList`](crate::ds::SetValueList) is used as data container in
387///     this case. The container keeps insertion order.
388///   * *release mode* : Vector does nothing to keep the deduplicated status.
389///     Clients must keep the status on their code. In this case, [`Vec`] is
390///     used as data container.
391///
392/// # How to determine `ON`
393///
394/// If sorting is not a burden to you, and you're going to insert/remove items
395/// in any orders, then set ON to `true`. The vector will keep the deduplicated
396/// status always.
397///
398/// If you can guarantee the deduplicated status on your own, then set ON to
399/// `false`. The vector will warn you if the guarantee has been broken in debug
400/// mode. In release mode, there won't be any additional operations to avoid
401/// performance penalty.
402#[repr(transparent)]
403pub struct DedupVec<T, const ON: bool = true>
404where
405    Self: AsDedupVec,
406{
407    inner: <Self as AsDedupVec>::Container,
408}
409
410impl<T, const ON: bool> fmt::Debug for DedupVec<T, ON>
411where
412    Self: AsDedupVec,
413    <Self as AsDedupVec>::Container: fmt::Debug,
414{
415    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
416        write!(f, "DedupVec({:?})", self.inner)
417    }
418}
419
420impl<T> From<DedupVec<T, true>> for Vec<T>
421where
422    T: Ord,
423{
424    fn from(value: DedupVec<T, true>) -> Self {
425        value.inner
426    }
427}
428
429#[cfg(not(debug_assertions))]
430impl<T> From<DedupVec<T, false>> for Vec<T>
431where
432    T: hash::Hash + Eq + Clone,
433{
434    fn from(value: DedupVec<T, false>) -> Self {
435        value.inner
436    }
437}
438
439#[cfg(debug_assertions)]
440impl<T> From<DedupVec<T, false>> for Vec<T>
441where
442    T: hash::Hash + Eq + Default + Clone,
443{
444    fn from(value: DedupVec<T, false>) -> Self {
445        value.inner.into()
446    }
447}