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}