my_ecs/ds/list.rs
1use super::OptVec;
2use std::{
3 collections::HashMap,
4 fmt::Display,
5 hash::{BuildHasher, Hash},
6 iter,
7 ops::{Deref, DerefMut},
8};
9
10/// A list containing unique values.
11///
12/// This list is based on [`SetList`]. See documentation of it for more
13/// information.
14#[derive(Debug)]
15#[repr(transparent)]
16pub struct SetValueList<V, S>(SetList<V, V, S>);
17
18impl<V, S> SetValueList<V, S>
19where
20 S: BuildHasher + Default,
21{
22 /// Creates a new empty list.
23 ///
24 /// [`SetValueList`] requires dummy head node for now, so you can put in any
25 /// values.
26 ///
27 /// # Examples
28 ///
29 /// ```
30 /// use my_ecs::ds::SetValueList;
31 /// use std::hash::RandomState;
32 ///
33 /// let list = SetValueList::<&'static str, RandomState>::new("");
34 /// ```
35 pub fn new(dummy: V) -> Self {
36 Self(SetList::new(dummy))
37 }
38}
39
40impl<V, S> Default for SetValueList<V, S>
41where
42 V: Default,
43 S: BuildHasher + Default,
44{
45 /// Creates a new empty list.
46 ///
47 /// # Examples
48 ///
49 /// ```
50 /// use my_ecs::ds::SetValueList;
51 /// use std::hash::RandomState;
52 ///
53 /// let list = SetValueList::<&'static str, RandomState>::default();
54 /// ```
55 fn default() -> Self {
56 Self(SetList::<V, V, S>::default())
57 }
58}
59
60impl<V, S> SetValueList<V, S>
61where
62 V: Hash + Eq + Clone,
63 S: BuildHasher,
64{
65 /// Appends the given value to the end of the list.
66 ///
67 /// However, if the list already contains the value, nothing takes place and
68 /// returns false.
69 ///
70 /// # Examples
71 ///
72 /// ```
73 /// use my_ecs::ds::SetValueList;
74 /// use std::hash::RandomState;
75 ///
76 /// let mut list = SetValueList::<_, RandomState>::default();
77 /// list.push_back("alpha");
78 /// assert!(!list.push_back("alpha"));
79 /// ```
80 pub fn push_back(&mut self, value: V) -> bool {
81 self.0.push_back(value.clone(), value)
82 }
83
84 /// Appends the given value to the beginning of the list.
85 ///
86 /// However, if the list already contains the value, nothing takes place and
87 /// returns false.
88 ///
89 /// # Examples
90 ///
91 /// ```
92 /// use my_ecs::ds::SetValueList;
93 /// use std::hash::RandomState;
94 ///
95 /// let mut list = SetValueList::<_, RandomState>::default();
96 /// list.push_front("alpha");
97 /// assert!(!list.push_front("alpha"));
98 /// ```
99 pub fn push_front(&mut self, value: V) -> bool {
100 self.0.push_front(value.clone(), value)
101 }
102}
103
104impl<V, S> Deref for SetValueList<V, S> {
105 type Target = SetList<V, V, S>;
106
107 fn deref(&self) -> &Self::Target {
108 &self.0
109 }
110}
111
112impl<V, S> DerefMut for SetValueList<V, S> {
113 fn deref_mut(&mut self) -> &mut Self::Target {
114 &mut self.0
115 }
116}
117
118impl<V, S> Clone for SetValueList<V, S>
119where
120 V: Clone,
121 S: Clone,
122{
123 fn clone(&self) -> Self {
124 Self(self.0.clone())
125 }
126}
127
128impl<V, S> Display for SetValueList<V, S>
129where
130 V: Display,
131 S: BuildHasher,
132{
133 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134 self.0.fmt(f)
135 }
136}
137
138impl<V, S> IntoIterator for SetValueList<V, S>
139where
140 S: BuildHasher,
141{
142 type Item = V;
143 type IntoIter = IntoValues<V, S>;
144
145 fn into_iter(self) -> Self::IntoIter {
146 self.0.into_values()
147 }
148}
149
150impl<V, S> From<&[V]> for SetValueList<V, S>
151where
152 V: Hash + Eq + Clone + Default,
153 S: BuildHasher + Default,
154{
155 fn from(value: &[V]) -> Self {
156 let mut list = Self::default();
157 for v in value.iter() {
158 list.push_back(v.clone());
159 }
160 list
161 }
162}
163
164impl<V, S> From<SetValueList<V, S>> for Vec<V>
165where
166 S: BuildHasher,
167{
168 fn from(value: SetValueList<V, S>) -> Self {
169 value.0.nodes.into_iter().map(|node| node.value).collect()
170 }
171}
172
173/// A list containg unique key-value pairs.
174///
175/// This is a list, but all items are laid on a single sequential memory block.
176/// Therefore, we can expect more speed in terms of iteration than standard
177/// linked list, [`LinkedList`](std::collections::LinkedList), but it requires
178/// more memory footprint.
179///
180/// # NOTE
181///
182/// Current implementation doesn't concern about ZST.
183#[derive(Debug)]
184pub struct SetList<K, V, S> {
185 nodes: OptVec<ListNode<V>, S>,
186 tail: ListPos,
187 map: HashMap<K, ListPos, S>,
188}
189
190impl<K, V, S> Default for SetList<K, V, S>
191where
192 V: Default,
193 S: BuildHasher + Default,
194{
195 /// Creates a new empty list.
196 ///
197 /// # Examples
198 ///
199 /// ```
200 /// use my_ecs::ds::SetList;
201 /// use std::hash::RandomState;
202 ///
203 /// let list = SetList::<char, String, RandomState>::default();
204 /// ```
205 fn default() -> Self {
206 Self::new(V::default())
207 }
208}
209
210impl<K, V, S> SetList<K, V, S>
211where
212 S: BuildHasher + Default,
213{
214 /// Creates a new empty list.
215 ///
216 /// [`SetList`] requires dummy head node for now, so you can put in any
217 /// values.
218 ///
219 /// # Examples
220 ///
221 /// ```
222 /// use my_ecs::ds::SetList;
223 /// use std::hash::RandomState;
224 ///
225 /// let list = SetList::<char, &'static str, RandomState>::new("");
226 /// ```
227 pub fn new(dummy: V) -> Self {
228 let mut nodes = OptVec::new();
229 let dummy_head_idx = nodes.add(ListNode {
230 prev: ListPos::end(),
231 next: ListPos::end(),
232 value: dummy,
233 });
234 let tail = ListPos(dummy_head_idx);
235
236 // Dummy node always occupies 0th slot in the OptVec. We consider that 0
237 // is END index of the list. See `ListPos::end` together.
238 debug_assert_eq!(ListPos::end(), tail);
239
240 Self {
241 nodes,
242 tail,
243 map: HashMap::default(),
244 }
245 }
246}
247
248impl<K, V, S> SetList<K, V, S> {
249 /// Returns number of items.
250 ///
251 /// # Examples
252 ///
253 /// ```
254 /// use my_ecs::ds::SetList;
255 /// use std::hash::RandomState;
256 ///
257 /// let mut list = SetList::<_, _, RandomState>::default();
258 /// list.push_back('a', "alpha");
259 /// assert_eq!(list.len(), 1);
260 /// ```
261 pub fn len(&self) -> usize {
262 self.nodes.len() - 1 /* dummy head node */
263 }
264
265 /// Returns true if the list is empty.
266 ///
267 /// # Examples
268 ///
269 /// ```
270 /// use my_ecs::ds::SetList;
271 /// use std::hash::RandomState;
272 ///
273 /// let mut list = SetList::<char, &'static str, RandomState>::default();
274 /// assert!(list.is_empty());
275 /// ```
276 pub fn is_empty(&self) -> bool {
277 self.len() == 0
278 }
279
280 /// Returns a shared reference to the front item.
281 ///
282 /// # Examples
283 ///
284 /// ```
285 /// use my_ecs::ds::SetList;
286 /// use std::hash::RandomState;
287 ///
288 /// let mut list = SetList::<_, _, RandomState>::default();
289 /// list.push_back('a', "alpha");
290 /// list.push_back('b', "beta");
291 /// assert_eq!(list.front(), Some(&"alpha"));
292 /// ```
293 pub fn front(&self) -> Option<&V> {
294 // Returns `None` for the dummy head node.
295 let first_pos = self.first_position();
296 if first_pos.is_end() {
297 return None;
298 }
299
300 // Safety: Position must be valid one: Ok.
301 unsafe { Some(self.get_value_unchecked(first_pos)) }
302 }
303
304 /// Returns a mutable reference to the front item.
305 ///
306 /// # Examples
307 ///
308 /// ```
309 /// use my_ecs::ds::SetList;
310 /// use std::hash::RandomState;
311 ///
312 /// let mut list = SetList::<_, _, RandomState>::default();
313 /// list.push_back('a', "alpha");
314 /// list.push_back('b', "beta");
315 /// assert_eq!(list.front_mut(), Some(&mut "alpha"));
316 /// ```
317 pub fn front_mut(&mut self) -> Option<&mut V> {
318 // Returns `None` for the dummy head node.
319 let first_pos = self.first_position();
320 if first_pos.is_end() {
321 return None;
322 }
323
324 // Safety: Position must be valid one: Ok.
325 unsafe { Some(self.get_value_unchecked_mut(first_pos)) }
326 }
327
328 /// Returns a shared reference to the last item.
329 ///
330 /// # Examples
331 ///
332 /// ```
333 /// use my_ecs::ds::SetList;
334 /// use std::hash::RandomState;
335 ///
336 /// let mut list = SetList::<_, _, RandomState>::default();
337 /// list.push_back('a', "alpha");
338 /// list.push_back('b', "beta");
339 /// assert_eq!(list.back(), Some(&"beta"));
340 /// ```
341 pub fn back(&self) -> Option<&V> {
342 // Returns `None` for the dummy head node.
343 if self.tail.is_end() {
344 return None;
345 }
346
347 // Safety: Position must be valid one: Ok.
348 unsafe { Some(self.get_value_unchecked(self.tail)) }
349 }
350
351 /// Returns a mutable reference to the last item.
352 ///
353 /// # Examples
354 ///
355 /// ```
356 /// use my_ecs::ds::SetList;
357 /// use std::hash::RandomState;
358 ///
359 /// let mut list = SetList::<_, _, RandomState>::default();
360 /// list.push_back('a', "alpha");
361 /// list.push_back('b', "beta");
362 /// assert_eq!(list.back_mut(), Some(&mut "beta"));
363 /// ```
364 pub fn back_mut(&mut self) -> Option<&mut V> {
365 // Returns `None` for the dummy head node.
366 if self.tail.is_end() {
367 return None;
368 }
369
370 // Safety: Position must be valid one: Ok.
371 unsafe { Some(self.get_value_unchecked_mut(self.tail)) }
372 }
373
374 /// Returns an iterator visiting all values in order.
375 ///
376 /// # Examples
377 ///
378 /// ```
379 /// use my_ecs::ds::SetList;
380 /// use std::hash::RandomState;
381 ///
382 /// let mut list = SetList::<_, _, RandomState>::default();
383 /// list.push_back('a', "alpha");
384 /// list.push_back('b', "beta");
385 ///
386 /// for v in list.values() {
387 /// println!("{v}"); // Prints out "alpha" and "beta".
388 /// }
389 /// ```
390 pub fn values(&self) -> Values<'_, V, S> {
391 self.values_from(self.first_position())
392 }
393
394 /// Returns a mutable iterator visiting all values in order.
395 ///
396 /// # Examples
397 ///
398 /// ```
399 /// use my_ecs::ds::SetList;
400 /// use std::hash::RandomState;
401 ///
402 /// let mut list = SetList::<_, _, RandomState>::default();
403 /// list.push_back('a', "alpha".to_owned());
404 /// list.push_back('b', "beta".to_owned());
405 ///
406 /// for v in list.values_mut() {
407 /// v.push('*');
408 /// println!("{v}"); // Prints out "alpha*" and "beta*".
409 /// }
410 /// ```
411 pub fn values_mut(&mut self) -> ValuesMut<'_, V, S> {
412 self.values_mut_from(self.first_position())
413 }
414
415 /// Returns an iterator visiting values from the given position.
416 ///
417 /// # Panics
418 ///
419 /// Panics if the position is not valid one for the list.
420 ///
421 /// # Examples
422 ///
423 /// ```
424 /// use my_ecs::ds::SetList;
425 /// use std::hash::RandomState;
426 ///
427 /// let mut list = SetList::<_, _, RandomState>::default();
428 /// list.push_back('a', "alpha");
429 /// list.push_back('b', "beta");
430 /// list.push_back('g', "gamma");
431 ///
432 /// let pos = list.get_position(&'b').unwrap();
433 /// for v in list.values_from(pos) {
434 /// println!("{v}"); // Prints out "beta" and "gamma".
435 /// }
436 /// ```
437 pub fn values_from(&self, cur: ListPos) -> Values<'_, V, S> {
438 assert!(
439 self.nodes.get(cur.into_inner()).is_some(),
440 "{cur:?} is not a valid position"
441 );
442
443 // `ListPos::end()` passes validation above due to the dummy head node.
444 // But it's Ok because `Values` will return `None` when it meets
445 // `ListPos::end()`.
446 Values {
447 nodes: &self.nodes,
448 cur,
449 }
450 }
451
452 /// Returns a mutable iterator visiting values from the given position.
453 ///
454 /// # Panics
455 ///
456 /// Panics if the position is not valid one for the list.
457 ///
458 /// # Examples
459 ///
460 /// ```
461 /// use my_ecs::ds::SetList;
462 /// use std::hash::RandomState;
463 ///
464 /// let mut list = SetList::<_, _, RandomState>::default();
465 /// list.push_back('a', "alpha".to_owned());
466 /// list.push_back('b', "beta".to_owned());
467 /// list.push_back('g', "gamma".to_owned());
468 ///
469 /// let pos = list.get_position(&'b').unwrap();
470 /// for v in list.values_mut_from(pos) {
471 /// v.push('*');
472 /// println!("{v}"); // Prints out "beta*" and "gamma*".
473 /// }
474 /// ```
475 pub fn values_mut_from(&mut self, cur: ListPos) -> ValuesMut<'_, V, S> {
476 assert!(
477 self.nodes.get(cur.into_inner()).is_some(),
478 "{cur:?} is not a valid position"
479 );
480
481 // `ListPos::end()` passes validation above due to the dummy head node.
482 // But it's Ok because `ValuesMut` will return `None` when it meets
483 // `ListPos::end()`.
484 ValuesMut {
485 nodes: &mut self.nodes,
486 cur,
487 }
488 }
489
490 /// Creates an iterator visiting all values in order by consuming the list.
491 ///
492 /// # Examples
493 ///
494 /// ```
495 /// use my_ecs::ds::SetList;
496 /// use std::hash::RandomState;
497 ///
498 /// let mut list = SetList::<_, _, RandomState>::default();
499 /// list.push_back('a', "alpha");
500 /// list.push_back('b', "beta");
501 ///
502 /// for v in list.into_values() {
503 /// println!("{v}");
504 /// }
505 /// ```
506 pub fn into_values(self) -> IntoValues<V, S> {
507 let pos = self.first_position();
508 self.into_values_from(pos)
509 }
510
511 /// Creates an iterator visiting values from the given position by consuming
512 /// the list.
513 ///
514 /// # Panics
515 ///
516 /// Panics if the position is not valid one for the list.
517 ///
518 /// # Examples
519 ///
520 /// ```
521 /// use my_ecs::ds::SetList;
522 /// use std::hash::RandomState;
523 ///
524 /// let mut list = SetList::<_, _, RandomState>::default();
525 /// list.push_back('a', "alpha");
526 /// list.push_back('b', "beta");
527 /// list.push_back('g', "gamma");
528 ///
529 /// let pos = list.get_position(&'b').unwrap();
530 /// for v in list.into_values_from(pos) {
531 /// println!("{v}"); // Prints out "beta" and "gamma".
532 /// }
533 /// ```
534 pub fn into_values_from(self, cur: ListPos) -> IntoValues<V, S> {
535 assert!(
536 self.nodes.get(cur.into_inner()).is_some(),
537 "{cur:?} is not a valid position"
538 );
539
540 // `ListPos::end()` passes validation above due to the dummy head node.
541 // But it's Ok because `IntoValues` will return `None` when it meets
542 // `ListPos::end()`.
543 IntoValues {
544 nodes: self.nodes,
545 cur,
546 }
547 }
548
549 /// Returns a shared reference to a value at the given position with the
550 /// next position.
551 ///
552 /// If the given position is not valid one for the list, returns None.
553 ///
554 /// # Examples
555 ///
556 /// ```
557 /// use my_ecs::ds::SetList;
558 /// use std::hash::RandomState;
559 ///
560 /// let mut list = SetList::<_, _, RandomState>::default();
561 /// list.push_back('a', "alpha");
562 /// list.push_back('b', "beta");
563 ///
564 /// let pos = list.get_position(&'b').unwrap();
565 /// let (_, v) = list.iter_next(pos).unwrap();
566 /// assert_eq!(v, &"beta");
567 /// ```
568 pub fn iter_next(&self, cur: ListPos) -> Option<(ListPos, &V)> {
569 // `ListPos::end()` must be ignored due to the dummy head node.
570 if cur.is_end() {
571 return None;
572 }
573
574 self.nodes
575 .get(cur.into_inner())
576 .map(|cur_node| (cur_node.next, &cur_node.value))
577 }
578
579 /// Returns a mutable reference to a value at the given position with the
580 /// next position.
581 ///
582 /// If the given position is not valid one for the list, returns None.
583 ///
584 /// # Examples
585 ///
586 /// ```
587 /// use my_ecs::ds::SetList;
588 /// use std::hash::RandomState;
589 ///
590 /// let mut list = SetList::<_, _, RandomState>::default();
591 /// list.push_back('a', "alpha");
592 /// list.push_back('b', "beta");
593 ///
594 /// let pos = list.get_position(&'b').unwrap();
595 /// let (_, v) = list.iter_next_mut(pos).unwrap();
596 /// assert_eq!(v, &mut "beta");
597 /// ```
598 pub fn iter_next_mut(&mut self, cur: ListPos) -> Option<(ListPos, &mut V)> {
599 // `ListPos::end()` must be ignored due to the dummy head node.
600 if cur.is_end() {
601 return None;
602 }
603
604 self.nodes
605 .get_mut(cur.into_inner())
606 .map(|cur_node| (cur_node.next, &mut cur_node.value))
607 }
608
609 /// Returns the first position of the list.
610 ///
611 /// # Examples
612 ///
613 /// ```
614 /// use my_ecs::ds::SetList;
615 /// use std::hash::RandomState;
616 ///
617 /// let mut list = SetList::<_, _, RandomState>::default();
618 /// list.push_back('a', "alpha");
619 /// list.push_back('b', "beta");
620 ///
621 /// let pos = list.first_position();
622 /// let (_, v) = list.iter_next(pos).unwrap();
623 /// assert_eq!(v, &"alpha");
624 /// ```
625 pub fn first_position(&self) -> ListPos {
626 // Safety: Dummy head occupies `ListPos::end()` so accessing it is safe.
627 // See constructor for more details.
628 let dummy_head_idx = ListPos::end().into_inner();
629 unsafe { self.nodes.get_unchecked(dummy_head_idx).next }
630 }
631
632 /// Returns a shared reference to a value at the given position.
633 ///
634 /// If the position is [`ListPos::end`], then the method returns value of
635 /// the dummy head node.
636 ///
637 /// # Safety
638 ///
639 /// Undefined behavior if the position is neither a valid one for the list
640 /// nor the `ListPos::end`.
641 unsafe fn get_value_unchecked(&self, pos: ListPos) -> &V {
642 let node = unsafe { self.nodes.get_unchecked(pos.into_inner()) };
643 &node.value
644 }
645
646 /// Returns a mutable reference to a value at the given position.
647 ///
648 /// If the position is [`ListPos::end`], then the method returns value of
649 /// the dummy head node.
650 ///
651 /// # Safety
652 ///
653 /// Undefined behavior if the position is neither a valid one for the list
654 /// nor the `ListPos::end`.
655 unsafe fn get_value_unchecked_mut(&mut self, pos: ListPos) -> &mut V {
656 let node = unsafe { self.nodes.get_unchecked_mut(pos.into_inner()) };
657 &mut node.value
658 }
659
660 fn get_default_head_node_mut(&mut self) -> &mut ListNode<V> {
661 // Safety: Dummy head occupies `ListPos::end()` so accessing it is safe.
662 // See constructor for more details.
663 let dummy_head_idx = ListPos::end().into_inner();
664 unsafe { self.nodes.get_unchecked_mut(dummy_head_idx) }
665 }
666}
667
668impl<K, V, S> SetList<K, V, S>
669where
670 K: Hash + Eq,
671 S: BuildHasher,
672{
673 /// Returns true if the vector contains the given key.
674 ///
675 /// # Examples
676 ///
677 /// ```
678 /// use my_ecs::ds::SetList;
679 /// use std::hash::RandomState;
680 ///
681 /// let mut list = SetList::<_, _, RandomState>::default();
682 /// list.push_back('a', "alpha");
683 /// assert!(list.contains_key(&'a'));
684 /// ```
685 pub fn contains_key<Q>(&self, key: &Q) -> bool
686 where
687 K: std::borrow::Borrow<Q>,
688 Q: Hash + Eq + ?Sized,
689 {
690 self.map.contains_key(key)
691 }
692
693 /// Retrieves a position of a value corresponding to the given key.
694 ///
695 /// # Examples
696 ///
697 /// ```
698 /// use my_ecs::ds::SetList;
699 /// use std::hash::RandomState;
700 ///
701 /// let mut list = SetList::<_, _, RandomState>::default();
702 /// list.push_back('a', "alpha");
703 /// let pos = list.get_position(&'a').unwrap();
704 /// ```
705 pub fn get_position<Q>(&self, key: &Q) -> Option<ListPos>
706 where
707 K: std::borrow::Borrow<Q>,
708 Q: Hash + Eq + ?Sized,
709 {
710 self.map.get(key).copied()
711 }
712
713 /// Retrieves a shared reference to a value corresponding to the given key.
714 ///
715 /// # Examples
716 ///
717 /// ```
718 /// use my_ecs::ds::SetList;
719 /// use std::hash::RandomState;
720 ///
721 /// let mut list = SetList::<_, _, RandomState>::default();
722 /// list.push_back('a', "alpha");
723 /// assert_eq!(list.get(&'a'), Some(&"alpha"));
724 /// ```
725 pub fn get<Q>(&self, key: &Q) -> Option<&V>
726 where
727 K: std::borrow::Borrow<Q>,
728 Q: Hash + Eq + ?Sized,
729 {
730 self.get_node(key).map(|node| &node.value)
731 }
732
733 /// Retrieves a mutable reference to a value corresponding to the given key.
734 ///
735 /// # Examples
736 ///
737 /// ```
738 /// use my_ecs::ds::SetList;
739 /// use std::hash::RandomState;
740 ///
741 /// let mut list = SetList::<_, _, RandomState>::default();
742 /// list.push_back('a', "alpha");
743 /// assert_eq!(list.get_mut(&'a'), Some(&mut "alpha"));
744 /// ```
745 pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
746 where
747 K: std::borrow::Borrow<Q>,
748 Q: Hash + Eq + ?Sized,
749 {
750 self.get_node_mut(key).map(|node| &mut node.value)
751 }
752
753 /// Appends the given key-value pair to the end of the list.
754 ///
755 /// However, if the list already contains the key, nothing takes place and
756 /// returns false.
757 ///
758 /// # Examples
759 ///
760 /// ```
761 /// use my_ecs::ds::SetList;
762 /// use std::hash::RandomState;
763 ///
764 /// let mut list = SetList::<_, _, RandomState>::default();
765 /// list.push_back('a', "alpha");
766 /// assert!(!list.push_back('a', "beta"));
767 /// assert_eq!(list.back(), Some(&"alpha"));
768 /// ```
769 pub fn push_back(&mut self, key: K, value: V) -> bool {
770 if self.contains_key(&key) {
771 return false;
772 }
773
774 // Appends new tail node.
775 let cur_index = self.nodes.add(ListNode {
776 prev: self.tail,
777 next: ListPos::end(),
778 value,
779 });
780 let cur_pos = ListPos(cur_index);
781
782 // Updates old tail node.
783 // Safety: We control self.tail is always valid.
784 let old_tail = unsafe { self.nodes.get_unchecked_mut(self.tail.into_inner()) };
785 old_tail.next = cur_pos;
786 self.tail = cur_pos;
787
788 // Updates imap.
789 self.map.insert(key, cur_pos);
790
791 true
792 }
793
794 /// Inserts the given key-value pair to the beginning of the list.
795 ///
796 /// However, if the list already contains the key, nothing takes place and
797 /// returns false.
798 ///
799 /// # Examples
800 ///
801 /// ```
802 /// use my_ecs::ds::SetList;
803 /// use std::hash::RandomState;
804 ///
805 /// let mut list = SetList::<_, _, RandomState>::default();
806 /// list.push_front('a', "alpha");
807 /// assert!(!list.push_front('a', "beta"));
808 /// assert_eq!(list.front(), Some(&"alpha"));
809 /// ```
810 pub fn push_front(&mut self, key: K, value: V) -> bool {
811 if self.contains_key(&key) {
812 return false;
813 }
814
815 // Appends new first node (the next node of default head node).
816 let first_pos = self.first_position();
817 let cur_index = self.nodes.add(ListNode {
818 prev: ListPos::end(),
819 next: first_pos,
820 value,
821 });
822 let cur_pos = ListPos(cur_index);
823
824 // Updates old first node.
825 if !first_pos.is_end() {
826 // Safety: first_index must be zero, which is default head node, or valid index.
827 let old_first = unsafe { self.nodes.get_unchecked_mut(first_pos.into_inner()) };
828 old_first.prev = cur_pos;
829 } else {
830 // Current node may be the first tail node.
831 self.tail = cur_pos;
832 }
833 self.get_default_head_node_mut().next = cur_pos;
834
835 // Updates imap.
836 self.map.insert(key, cur_pos);
837
838 true
839 }
840
841 /// Inserts the given `key`-`value` pair after a node corresponding to
842 /// `after`.
843 ///
844 /// However, if the list already contains the `key` or doesn't contain
845 /// `after`, nothing takes place and returns false.
846 ///
847 /// # Examples
848 ///
849 /// ```
850 /// use my_ecs::ds::SetList;
851 /// use std::hash::RandomState;
852 ///
853 /// let mut list = SetList::<_, _, RandomState>::default();
854 /// list.push_back('a', "alpha");
855 /// list.push_back('g', "gamma");
856 /// list.insert('b', "beta", &'a');
857 /// ```
858 pub fn insert<Q>(&mut self, key: K, value: V, after: &Q) -> bool
859 where
860 K: std::borrow::Borrow<Q>,
861 Q: Hash + Eq + ?Sized,
862 {
863 if self.contains_key(key.borrow()) {
864 return false;
865 }
866
867 if let Some(&after_pos) = self.map.get(after) {
868 let after_idx = after_pos.into_inner();
869
870 // Creates a new node.
871 // Safety: Infallible.
872 let next_pos = unsafe { self.nodes.get_unchecked_mut(after_idx).next };
873 let cur_index = self.nodes.add(ListNode {
874 prev: after_pos,
875 next: next_pos,
876 value,
877 });
878 let cur_pos = ListPos(cur_index);
879
880 // Updates links of `after` and `next` nodes.
881 // Safety: Infallible.
882 unsafe {
883 self.nodes.get_unchecked_mut(after_idx).next = cur_pos;
884 if !next_pos.is_end() {
885 self.nodes.get_unchecked_mut(next_pos.into_inner()).prev = cur_pos;
886 } else {
887 self.tail = cur_pos;
888 }
889 }
890
891 // Updates imap.
892 self.map.insert(key, cur_pos);
893
894 true
895 } else {
896 false
897 }
898 }
899
900 /// Removes an item corresponding to the given key.
901 ///
902 /// # Examples
903 ///
904 /// ```
905 /// use my_ecs::ds::SetList;
906 /// use std::hash::RandomState;
907 ///
908 /// let mut list = SetList::<_, _, RandomState>::default();
909 /// list.push_back('a', "alpha");
910 /// assert_eq!(list.remove(&'a'), Some("alpha"));
911 /// ```
912 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
913 where
914 K: std::borrow::Borrow<Q>,
915 Q: Hash + Eq + ?Sized,
916 {
917 self.remove_entry(key).map(|(_, value)| value)
918 }
919
920 /// Removes an item corresponding to the given key then resturns key-value
921 /// pair.
922 ///
923 /// # Examples
924 ///
925 /// ```
926 /// use my_ecs::ds::SetList;
927 /// use std::hash::RandomState;
928 ///
929 /// let mut list = SetList::<_, _, RandomState>::default();
930 /// list.push_back('a', "alpha");
931 /// assert_eq!(list.remove_entry(&'a'), Some(('a', "alpha")));
932 /// ```
933 pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
934 where
935 K: std::borrow::Borrow<Q>,
936 Q: Hash + Eq + ?Sized,
937 {
938 let (key, pos) = self.map.remove_entry(key)?;
939 let old = unsafe { self.nodes.take(pos.into_inner()).unwrap_unchecked() };
940 let prev_pos = old.prev;
941 let next_pos = old.next;
942 unsafe {
943 self.nodes.get_unchecked_mut(prev_pos.into_inner()).next = next_pos;
944 if !next_pos.is_end() {
945 self.nodes.get_unchecked_mut(next_pos.into_inner()).prev = prev_pos;
946 } else {
947 self.tail = prev_pos;
948 }
949 }
950 Some((key, old.value))
951 }
952
953 fn get_node<Q>(&self, key: &Q) -> Option<&ListNode<V>>
954 where
955 K: std::borrow::Borrow<Q>,
956 Q: Hash + Eq + ?Sized,
957 {
958 let pos = self.map.get(key)?;
959 self.nodes.get(pos.into_inner())
960 }
961
962 fn get_node_mut<Q>(&mut self, key: &Q) -> Option<&mut ListNode<V>>
963 where
964 K: std::borrow::Borrow<Q>,
965 Q: Hash + Eq + ?Sized,
966 {
967 let pos = self.map.get(key)?;
968 self.nodes.get_mut(pos.into_inner())
969 }
970}
971
972impl<K, V, S> SetList<K, V, S>
973where
974 V: Clone,
975 S: BuildHasher,
976{
977 /// Creates `Vec` from this list.
978 pub fn values_as_vec(&self) -> Vec<V> {
979 let mut v = Vec::new();
980 for value in self.values() {
981 v.push(value.clone());
982 }
983 v
984 }
985}
986
987impl<K, V, S> Clone for SetList<K, V, S>
988where
989 K: Clone,
990 V: Clone,
991 S: Clone,
992{
993 fn clone(&self) -> Self {
994 Self {
995 nodes: self.nodes.clone(),
996 tail: self.tail,
997 map: self.map.clone(),
998 }
999 }
1000}
1001
1002impl<K, V, S> Display for SetList<K, V, S>
1003where
1004 V: Display,
1005 S: BuildHasher,
1006{
1007 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1008 write!(f, "[")?;
1009 let last = self.len() - 1;
1010 for (i, value) in self.values().enumerate() {
1011 if i == last {
1012 write!(f, "{value}")?;
1013 } else {
1014 write!(f, "{value}, ")?;
1015 }
1016 }
1017 write!(f, "]")
1018 }
1019}
1020
1021impl<K, V, S> IntoIterator for SetList<K, V, S>
1022where
1023 S: BuildHasher,
1024{
1025 type Item = (K, V);
1026 type IntoIter = IntoIter<K, V, S>;
1027
1028 fn into_iter(self) -> Self::IntoIter {
1029 IntoIter::new(self)
1030 }
1031}
1032
1033impl<K, V, S> From<&[(K, V)]> for SetList<K, V, S>
1034where
1035 K: Hash + Eq + Clone,
1036 V: Default + Clone,
1037 S: BuildHasher + Default,
1038{
1039 fn from(value: &[(K, V)]) -> Self {
1040 let mut list = Self::default();
1041 for (k, v) in value.iter() {
1042 list.push_back(k.clone(), v.clone());
1043 }
1044 list
1045 }
1046}
1047
1048/// A position to an item of [`SetList`].
1049#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1050#[repr(transparent)]
1051pub struct ListPos(usize);
1052
1053impl ListPos {
1054 /// Creates a [`ListPos`] meaning end of list.
1055 pub const fn end() -> Self {
1056 Self(0)
1057 }
1058
1059 /// Returns true if the position is end.
1060 pub const fn is_end(&self) -> bool {
1061 self.0 == 0
1062 }
1063
1064 /// Returns inner index by consuming `self`.
1065 pub const fn into_inner(self) -> usize {
1066 self.0
1067 }
1068}
1069
1070#[derive(Debug, Clone)]
1071struct ListNode<V> {
1072 prev: ListPos,
1073 next: ListPos,
1074 value: V,
1075}
1076
1077/// An iterator yielding shared references to values of [`SetList`].
1078///
1079/// You can create the iterator by calling [`SetList::values`]. See the
1080/// documentation of the method for more information.
1081#[derive(Debug, Clone)]
1082pub struct Values<'a, V, S> {
1083 nodes: &'a OptVec<ListNode<V>, S>,
1084 cur: ListPos,
1085}
1086
1087impl<'a, V, S> Iterator for Values<'a, V, S> {
1088 type Item = &'a V;
1089
1090 fn next(&mut self) -> Option<Self::Item> {
1091 if !self.cur.is_end() {
1092 // Safety: self.cur is always valid.
1093 let node = unsafe { self.nodes.get_unchecked(self.cur.into_inner()) };
1094 self.cur = node.next;
1095 Some(&node.value)
1096 } else {
1097 None
1098 }
1099 }
1100}
1101
1102impl<V, S> iter::FusedIterator for Values<'_, V, S> {}
1103
1104/// An iterator yielding mutable references to values of [`SetList`].
1105///
1106/// You can create the iterator by calling [`SetList::values_mut`]. See the
1107/// documentation of the method for more information.
1108#[derive(Debug)]
1109pub struct ValuesMut<'a, V, S> {
1110 nodes: &'a mut OptVec<ListNode<V>, S>,
1111 cur: ListPos,
1112}
1113
1114impl<'a, V, S> Iterator for ValuesMut<'a, V, S> {
1115 type Item = &'a mut V;
1116
1117 fn next(&mut self) -> Option<Self::Item> {
1118 if !self.cur.is_end() {
1119 // Safety: self.cur is always valid.
1120 let node = unsafe { self.nodes.get_unchecked_mut(self.cur.into_inner()) };
1121 self.cur = node.next;
1122 let ptr = std::ptr::addr_of_mut!(node.value);
1123 // Safety: Infallible.
1124 unsafe { ptr.as_mut() }
1125 } else {
1126 None
1127 }
1128 }
1129}
1130
1131impl<V, S> iter::FusedIterator for ValuesMut<'_, V, S> {}
1132
1133/// An owning iteartor over values of [`SetList`].
1134///
1135/// You can create the iterator by calling [`SetList::into_values`]. See the
1136/// documentation of the method for more information.
1137#[derive(Debug)]
1138pub struct IntoValues<V, S> {
1139 nodes: OptVec<ListNode<V>, S>,
1140 cur: ListPos,
1141}
1142
1143impl<V, S> Iterator for IntoValues<V, S>
1144where
1145 S: BuildHasher,
1146{
1147 type Item = V;
1148
1149 fn next(&mut self) -> Option<Self::Item> {
1150 if !self.cur.is_end() {
1151 // Safety: self.cur is always valid.
1152 let node = unsafe { self.nodes.take(self.cur.into_inner()).unwrap_unchecked() };
1153 self.cur = node.next;
1154 Some(node.value)
1155 } else {
1156 None
1157 }
1158 }
1159}
1160
1161impl<V, S: BuildHasher> iter::FusedIterator for IntoValues<V, S> {}
1162
1163/// An owning iterator over key-value pairs of [`SetList`].
1164///
1165/// You can create the iterator by calling [`SetList::into_iter`]. See the
1166/// documentation of the method for more information.
1167#[derive(Debug)]
1168pub struct IntoIter<K, V, S> {
1169 nodes: OptVec<ListNode<V>, S>,
1170 map_iter: std::collections::hash_map::IntoIter<K, ListPos>,
1171}
1172
1173impl<K, V, S> IntoIter<K, V, S> {
1174 fn new(list: SetList<K, V, S>) -> Self {
1175 Self {
1176 nodes: list.nodes,
1177 map_iter: list.map.into_iter(),
1178 }
1179 }
1180}
1181
1182impl<K, V, S> Iterator for IntoIter<K, V, S>
1183where
1184 S: BuildHasher,
1185{
1186 type Item = (K, V);
1187
1188 fn next(&mut self) -> Option<Self::Item> {
1189 if let Some((k, pos)) = self.map_iter.next() {
1190 // Safety: We got the index from the map, so the slot must be
1191 // occupied.
1192 let node = unsafe { self.nodes.take(pos.into_inner()).unwrap_unchecked() };
1193 Some((k, node.value))
1194 } else {
1195 None
1196 }
1197 }
1198}
1199
1200// We can implement ExactSizeIterator because hash_map::IntoIter implements it.
1201impl<K, V, S: BuildHasher> ExactSizeIterator for IntoIter<K, V, S> {
1202 fn len(&self) -> usize {
1203 self.map_iter.len()
1204 }
1205}
1206
1207// We can implement FusedIterator because hash_map::IntoIter implements it.
1208impl<K, V, S: BuildHasher> iter::FusedIterator for IntoIter<K, V, S> {}
1209
1210#[cfg(test)]
1211mod tests {
1212 use super::*;
1213 use std::hash::RandomState;
1214
1215 #[test]
1216 fn test_setlist() {
1217 // push
1218 let mut list = SetValueList::<_, RandomState>::default();
1219 list.push_front(1);
1220 list.push_back(2);
1221 list.push_front(0);
1222 assert_eq!(3, list.len());
1223 let mut iter = list.values();
1224 assert_eq!(Some(&0), iter.next());
1225 assert_eq!(Some(&1), iter.next());
1226 assert_eq!(Some(&2), iter.next());
1227 assert_eq!(None, iter.next());
1228
1229 // as_vec
1230 assert_eq!(vec![0, 1, 2], list.values_as_vec());
1231
1232 // take 1
1233 assert_eq!(Some(1), list.remove(&1));
1234 let mut iter = list.values();
1235 assert_eq!(Some(&0), iter.next());
1236 assert_eq!(Some(&2), iter.next());
1237 assert_eq!(None, iter.next());
1238 assert_eq!(2, list.len());
1239 // take 2
1240 assert_eq!(Some(2), list.remove(&2));
1241 let mut iter = list.values();
1242 assert_eq!(Some(&0), iter.next());
1243 assert_eq!(None, iter.next());
1244 assert_eq!(1, list.len());
1245 // take 0
1246 assert_eq!(Some(0), list.remove(&0));
1247 let mut iter = list.values();
1248 assert_eq!(None, iter.next());
1249 assert_eq!(0, list.len());
1250
1251 // from<&[T]>
1252 let slice = &['a', 'b', 'c'][..];
1253 assert_eq!(
1254 Vec::from(slice),
1255 SetValueList::<_, RandomState>::from(slice).values_as_vec()
1256 );
1257
1258 // mutable iterator
1259 let src = [0, 1, 2];
1260 let mut list = SetValueList::<_, RandomState>::from(&src[..]);
1261 for value in list.values_mut() {
1262 *value *= 2;
1263 }
1264 for (src, dst) in src.iter().cloned().zip(list.values().cloned()) {
1265 assert_eq!(src * 2, dst);
1266 }
1267 // iterator from
1268 let cur = list.first_position();
1269 let (next, v) = list.iter_next_mut(cur).unwrap();
1270 *v /= 2;
1271 for v in list.values_mut_from(next) {
1272 *v /= 2;
1273 }
1274 for (src, dst) in src.iter().cloned().zip(list.values().cloned()) {
1275 assert_eq!(src, dst);
1276 }
1277 }
1278
1279 #[test]
1280 fn test_setlist_into_iter() {
1281 let mut list = SetValueList::<_, RandomState>::default();
1282 for i in 0..10 {
1283 list.push_back(i);
1284 }
1285
1286 let values = list.into_iter();
1287 for (i, value) in values.enumerate() {
1288 assert_eq!(value, i as i32);
1289 }
1290 }
1291}