1use crate::packed_option::ReservedValue;
3use crate::EntityRef;
4use alloc::vec::Vec;
5use core::marker::PhantomData;
6use core::mem;
7
8#[cfg(feature = "enable-serde")]
9use serde_derive::{Deserialize, Serialize};
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
66#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
67pub struct EntityList<T: EntityRef + ReservedValue> {
68 index: u32,
69 unused: PhantomData<T>,
70}
71
72impl<T: EntityRef + ReservedValue> Default for EntityList<T> {
74 fn default() -> Self {
75 Self {
76 index: 0,
77 unused: PhantomData,
78 }
79 }
80}
81
82#[derive(Clone, Debug)]
84#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
85pub struct ListPool<T: EntityRef + ReservedValue> {
86 data: Vec<T>,
88
89 free: Vec<usize>,
91}
92
93impl<T: EntityRef + ReservedValue> PartialEq for ListPool<T> {
94 fn eq(&self, other: &Self) -> bool {
95 self.data == other.data
97 }
98}
99
100impl<T: core::hash::Hash + EntityRef + ReservedValue> core::hash::Hash for ListPool<T> {
101 fn hash<H: __core::hash::Hasher>(&self, state: &mut H) {
102 self.data.hash(state);
104 }
105}
106
107impl<T: EntityRef + ReservedValue> Default for ListPool<T> {
108 fn default() -> Self {
109 Self::new()
110 }
111}
112
113type SizeClass = u8;
116
117#[inline]
120fn sclass_size(sclass: SizeClass) -> usize {
121 4 << sclass
122}
123
124#[inline]
127fn sclass_for_length(len: usize) -> SizeClass {
128 30 - (len as u32 | 3).leading_zeros() as SizeClass
129}
130
131#[inline]
133fn is_sclass_min_length(len: usize) -> bool {
134 len > 3 && len.is_power_of_two()
135}
136
137impl<T: EntityRef + ReservedValue> ListPool<T> {
138 pub fn new() -> Self {
140 Self {
141 data: Vec::new(),
142 free: Vec::new(),
143 }
144 }
145
146 pub fn with_capacity(len: usize) -> Self {
148 Self {
149 data: Vec::with_capacity(len),
150 free: Vec::new(),
151 }
152 }
153
154 pub fn capacity(&self) -> usize {
161 self.data.capacity()
162 }
163
164 pub fn clear(&mut self) {
171 self.data.clear();
172 self.free.clear();
173 }
174
175 fn len_of(&self, list: &EntityList<T>) -> Option<usize> {
177 let idx = list.index as usize;
178 self.data.get(idx.wrapping_sub(1)).map(|len| len.index())
185 }
186
187 fn alloc(&mut self, sclass: SizeClass) -> usize {
193 match self.free.get(sclass as usize).cloned() {
195 Some(head) if head > 0 => {
196 self.free[sclass as usize] = self.data[head].index();
201 head - 1
202 }
203 _ => {
204 let offset = self.data.len();
206 self.data
207 .resize(offset + sclass_size(sclass), T::reserved_value());
208 offset
209 }
210 }
211 }
212
213 fn free(&mut self, block: usize, sclass: SizeClass) {
217 let sclass = sclass as usize;
218
219 if self.free.len() <= sclass {
221 self.free.resize(sclass + 1, 0);
222 }
223
224 self.data[block] = T::new(0);
226 self.data[block + 1] = T::new(self.free[sclass]);
228 self.free[sclass] = block + 1
229 }
230
231 fn mut_slices(&mut self, block0: usize, block1: usize) -> (&mut [T], &mut [T]) {
236 if block0 < block1 {
237 let (s0, s1) = self.data.split_at_mut(block1);
238 (&mut s0[block0..], s1)
239 } else {
240 let (s1, s0) = self.data.split_at_mut(block0);
241 (s0, &mut s1[block1..])
242 }
243 }
244
245 fn realloc(
249 &mut self,
250 block: usize,
251 from_sclass: SizeClass,
252 to_sclass: SizeClass,
253 elems_to_copy: usize,
254 ) -> usize {
255 debug_assert!(elems_to_copy <= sclass_size(from_sclass));
256 debug_assert!(elems_to_copy <= sclass_size(to_sclass));
257 let new_block = self.alloc(to_sclass);
258
259 if elems_to_copy > 0 {
260 let (old, new) = self.mut_slices(block, new_block);
261 (&mut new[0..elems_to_copy]).copy_from_slice(&old[0..elems_to_copy]);
262 }
263
264 self.free(block, from_sclass);
265 new_block
266 }
267}
268
269impl<T: EntityRef + ReservedValue> EntityList<T> {
270 pub fn new() -> Self {
272 Default::default()
273 }
274
275 pub fn from_slice(slice: &[T], pool: &mut ListPool<T>) -> Self {
277 let len = slice.len();
278 if len == 0 {
279 return Self::new();
280 }
281
282 let block = pool.alloc(sclass_for_length(len));
283 pool.data[block] = T::new(len);
284 pool.data[block + 1..=block + len].copy_from_slice(slice);
285
286 Self {
287 index: (block + 1) as u32,
288 unused: PhantomData,
289 }
290 }
291
292 pub fn is_empty(&self) -> bool {
294 self.index == 0
297 }
298
299 pub fn len(&self, pool: &ListPool<T>) -> usize {
301 pool.len_of(self).unwrap_or(0)
303 }
304
305 pub fn is_valid(&self, pool: &ListPool<T>) -> bool {
307 self.is_empty() || pool.len_of(self) != None
309 }
310
311 pub fn as_slice<'a>(&self, pool: &'a ListPool<T>) -> &'a [T] {
313 let idx = self.index as usize;
314 match pool.len_of(self) {
315 None => &[],
316 Some(len) => &pool.data[idx..idx + len],
317 }
318 }
319
320 pub fn get(&self, index: usize, pool: &ListPool<T>) -> Option<T> {
322 self.as_slice(pool).get(index).cloned()
323 }
324
325 pub fn first(&self, pool: &ListPool<T>) -> Option<T> {
327 if self.is_empty() {
328 None
329 } else {
330 Some(pool.data[self.index as usize])
331 }
332 }
333
334 pub fn as_mut_slice<'a>(&'a mut self, pool: &'a mut ListPool<T>) -> &'a mut [T] {
336 let idx = self.index as usize;
337 match pool.len_of(self) {
338 None => &mut [],
339 Some(len) => &mut pool.data[idx..idx + len],
340 }
341 }
342
343 pub fn get_mut<'a>(&'a mut self, index: usize, pool: &'a mut ListPool<T>) -> Option<&'a mut T> {
345 self.as_mut_slice(pool).get_mut(index)
346 }
347
348 pub fn deep_clone(&self, pool: &mut ListPool<T>) -> Self {
350 match pool.len_of(self) {
351 None => return Self::new(),
352 Some(len) => {
353 let src = self.index as usize;
354 let block = pool.alloc(sclass_for_length(len));
355 pool.data[block] = T::new(len);
356 pool.data.copy_within(src..src + len, block + 1);
357
358 Self {
359 index: (block + 1) as u32,
360 unused: PhantomData,
361 }
362 }
363 }
364 }
365
366 pub fn clear(&mut self, pool: &mut ListPool<T>) {
370 let idx = self.index as usize;
371 match pool.len_of(self) {
372 None => debug_assert_eq!(idx, 0, "Invalid pool"),
373 Some(len) => pool.free(idx - 1, sclass_for_length(len)),
374 }
375 self.index = 0;
377 }
378
379 pub fn take(&mut self) -> Self {
383 mem::replace(self, Default::default())
384 }
385
386 pub fn push(&mut self, element: T, pool: &mut ListPool<T>) -> usize {
389 let idx = self.index as usize;
390 match pool.len_of(self) {
391 None => {
392 debug_assert_eq!(idx, 0, "Invalid pool");
394 let block = pool.alloc(sclass_for_length(1));
395 pool.data[block] = T::new(1);
396 pool.data[block + 1] = element;
397 self.index = (block + 1) as u32;
398 0
399 }
400 Some(len) => {
401 let new_len = len + 1;
403 let block;
404 if is_sclass_min_length(new_len) {
405 let sclass = sclass_for_length(len);
407 block = pool.realloc(idx - 1, sclass, sclass + 1, len + 1);
408 self.index = (block + 1) as u32;
409 } else {
410 block = idx - 1;
411 }
412 pool.data[block + new_len] = element;
413 pool.data[block] = T::new(new_len);
414 len
415 }
416 }
417 }
418
419 fn grow<'a>(&'a mut self, count: usize, pool: &'a mut ListPool<T>) -> &'a mut [T] {
423 let idx = self.index as usize;
424 let new_len;
425 let block;
426 match pool.len_of(self) {
427 None => {
428 debug_assert_eq!(idx, 0, "Invalid pool");
430 if count == 0 {
431 return &mut [];
432 }
433 new_len = count;
434 block = pool.alloc(sclass_for_length(new_len));
435 self.index = (block + 1) as u32;
436 }
437 Some(len) => {
438 let sclass = sclass_for_length(len);
440 new_len = len + count;
441 let new_sclass = sclass_for_length(new_len);
442 if new_sclass != sclass {
443 block = pool.realloc(idx - 1, sclass, new_sclass, len + 1);
444 self.index = (block + 1) as u32;
445 } else {
446 block = idx - 1;
447 }
448 }
449 }
450 pool.data[block] = T::new(new_len);
451 &mut pool.data[block + 1..block + 1 + new_len]
452 }
453
454 pub fn from_iter<I>(elements: I, pool: &mut ListPool<T>) -> Self
456 where
457 I: IntoIterator<Item = T>,
458 {
459 let mut list = Self::new();
460 list.extend(elements, pool);
461 list
462 }
463
464 pub fn extend<I>(&mut self, elements: I, pool: &mut ListPool<T>)
466 where
467 I: IntoIterator<Item = T>,
468 {
469 let iterator = elements.into_iter();
470 let (len, upper) = iterator.size_hint();
471 if upper == Some(len) {
473 let data = self.grow(len, pool);
474 let offset = data.len() - len;
475 for (src, dst) in iterator.zip(data[offset..].iter_mut()) {
476 *dst = src;
477 }
478 } else {
479 for x in iterator {
480 self.push(x, pool);
481 }
482 }
483 }
484
485 pub fn copy_from(
489 &mut self,
490 other: &Self,
491 slice: impl core::ops::RangeBounds<usize>,
492 index: usize,
493 pool: &mut ListPool<T>,
494 ) {
495 assert!(
496 index <= self.len(pool),
497 "attempted to copy a slice out of bounds of `self`"
498 );
499 assert_ne!(
500 self.index, other.index,
501 "cannot copy within one `EntityList`"
502 );
503
504 let (other_index, other_len) = (other.index, other.len(pool));
505
506 let start = match slice.start_bound() {
507 core::ops::Bound::Included(&x) => x,
508 core::ops::Bound::Excluded(&x) => x + 1,
509 core::ops::Bound::Unbounded => 0,
510 } + other_index as usize;
511 let end = match slice.end_bound() {
512 core::ops::Bound::Included(&x) => x + 1,
513 core::ops::Bound::Excluded(&x) => x,
514 core::ops::Bound::Unbounded => other_len,
515 } + other_index as usize;
516 let count = end - start;
517 assert!(
518 count <= other_len,
519 "attempted to copy a slice from out of bounds of `other`"
520 );
521
522 self.grow_at(index, count, pool);
523 pool.data
524 .copy_within(start..end, index + self.index as usize);
525 }
526
527 pub fn insert(&mut self, index: usize, element: T, pool: &mut ListPool<T>) {
530 self.push(element, pool);
532
533 let seq = self.as_mut_slice(pool);
535 if index < seq.len() {
536 let tail = &mut seq[index..];
537 for i in (1..tail.len()).rev() {
538 tail[i] = tail[i - 1];
539 }
540 tail[0] = element;
541 } else {
542 debug_assert_eq!(index, seq.len());
543 }
544 }
545
546 fn remove_last(&mut self, len: usize, pool: &mut ListPool<T>) {
548 if len == 1 {
550 self.clear(pool);
551 return;
552 }
553
554 let mut block = self.index as usize - 1;
556 if is_sclass_min_length(len) {
557 let sclass = sclass_for_length(len);
558 block = pool.realloc(block, sclass, sclass - 1, len);
559 self.index = (block + 1) as u32;
560 }
561
562 pool.data[block] = T::new(len - 1);
564 }
565
566 pub fn remove(&mut self, index: usize, pool: &mut ListPool<T>) {
568 let len;
569 {
570 let seq = self.as_mut_slice(pool);
571 len = seq.len();
572 debug_assert!(index < len);
573
574 for i in index..len - 1 {
576 seq[i] = seq[i + 1];
577 }
578 }
579
580 self.remove_last(len, pool);
581 }
582
583 pub fn swap_remove(&mut self, index: usize, pool: &mut ListPool<T>) {
586 let seq = self.as_mut_slice(pool);
587 let len = seq.len();
588 debug_assert!(index < len);
589 if index != len - 1 {
590 seq.swap(index, len - 1);
591 }
592
593 self.remove_last(len, pool);
594 }
595
596 pub fn truncate(&mut self, new_len: usize, pool: &mut ListPool<T>) {
600 if new_len == 0 {
601 self.clear(pool);
602 return;
603 }
604
605 match pool.len_of(self) {
606 None => return,
607 Some(len) => {
608 if len <= new_len {
609 return;
610 }
611
612 let block;
613 let idx = self.index as usize;
614 let sclass = sclass_for_length(len);
615 let new_sclass = sclass_for_length(new_len);
616 if sclass != new_sclass {
617 block = pool.realloc(idx - 1, sclass, new_sclass, new_len + 1);
618 self.index = (block + 1) as u32;
619 } else {
620 block = idx - 1;
621 }
622 pool.data[block] = T::new(new_len);
623 }
624 }
625 }
626
627 pub fn grow_at(&mut self, index: usize, count: usize, pool: &mut ListPool<T>) {
633 let data = self.grow(count, pool);
634
635 for i in (index + count..data.len()).rev() {
637 data[i] = data[i - count];
638 }
639 }
640}
641
642#[cfg(test)]
643mod tests {
644 use super::*;
645
646 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
648 pub struct Inst(u32);
649 entity_impl!(Inst, "inst");
650
651 #[test]
652 fn size_classes() {
653 assert_eq!(sclass_size(0), 4);
654 assert_eq!(sclass_for_length(0), 0);
655 assert_eq!(sclass_for_length(1), 0);
656 assert_eq!(sclass_for_length(2), 0);
657 assert_eq!(sclass_for_length(3), 0);
658 assert_eq!(sclass_for_length(4), 1);
659 assert_eq!(sclass_for_length(7), 1);
660 assert_eq!(sclass_for_length(8), 2);
661 assert_eq!(sclass_size(1), 8);
662 for l in 0..300 {
663 assert!(sclass_size(sclass_for_length(l)) >= l + 1);
664 }
665 }
666
667 #[test]
668 fn block_allocator() {
669 let mut pool = ListPool::<Inst>::new();
670 let b1 = pool.alloc(0);
671 let b2 = pool.alloc(1);
672 let b3 = pool.alloc(0);
673 assert_ne!(b1, b2);
674 assert_ne!(b1, b3);
675 assert_ne!(b2, b3);
676 pool.free(b2, 1);
677 let b2a = pool.alloc(1);
678 let b2b = pool.alloc(1);
679 assert_ne!(b2a, b2b);
680 assert!(b2a == b2 || b2b == b2);
682
683 pool.free(b1, 0);
685 pool.free(b3, 0);
686 let b1a = pool.alloc(0);
687 let b3a = pool.alloc(0);
688 assert_ne!(b1a, b3a);
689 assert!(b1a == b1 || b1a == b3);
690 assert!(b3a == b1 || b3a == b3);
691 }
692
693 #[test]
694 fn empty_list() {
695 let pool = &mut ListPool::<Inst>::new();
696 let mut list = EntityList::<Inst>::default();
697 {
698 let ilist = &list;
699 assert!(ilist.is_empty());
700 assert_eq!(ilist.len(pool), 0);
701 assert_eq!(ilist.as_slice(pool), &[]);
702 assert_eq!(ilist.get(0, pool), None);
703 assert_eq!(ilist.get(100, pool), None);
704 }
705 assert_eq!(list.as_mut_slice(pool), &[]);
706 assert_eq!(list.get_mut(0, pool), None);
707 assert_eq!(list.get_mut(100, pool), None);
708
709 list.clear(pool);
710 assert!(list.is_empty());
711 assert_eq!(list.len(pool), 0);
712 assert_eq!(list.as_slice(pool), &[]);
713 assert_eq!(list.first(pool), None);
714 }
715
716 #[test]
717 fn from_slice() {
718 let pool = &mut ListPool::<Inst>::new();
719
720 let list = EntityList::<Inst>::from_slice(&[Inst(0), Inst(1)], pool);
721 assert!(!list.is_empty());
722 assert_eq!(list.len(pool), 2);
723 assert_eq!(list.as_slice(pool), &[Inst(0), Inst(1)]);
724 assert_eq!(list.get(0, pool), Some(Inst(0)));
725 assert_eq!(list.get(100, pool), None);
726
727 let list = EntityList::<Inst>::from_slice(&[], pool);
728 assert!(list.is_empty());
729 assert_eq!(list.len(pool), 0);
730 assert_eq!(list.as_slice(pool), &[]);
731 assert_eq!(list.get(0, pool), None);
732 assert_eq!(list.get(100, pool), None);
733 }
734
735 #[test]
736 fn push() {
737 let pool = &mut ListPool::<Inst>::new();
738 let mut list = EntityList::<Inst>::default();
739
740 let i1 = Inst::new(1);
741 let i2 = Inst::new(2);
742 let i3 = Inst::new(3);
743 let i4 = Inst::new(4);
744
745 assert_eq!(list.push(i1, pool), 0);
746 assert_eq!(list.len(pool), 1);
747 assert!(!list.is_empty());
748 assert_eq!(list.as_slice(pool), &[i1]);
749 assert_eq!(list.first(pool), Some(i1));
750 assert_eq!(list.get(0, pool), Some(i1));
751 assert_eq!(list.get(1, pool), None);
752
753 assert_eq!(list.push(i2, pool), 1);
754 assert_eq!(list.len(pool), 2);
755 assert!(!list.is_empty());
756 assert_eq!(list.as_slice(pool), &[i1, i2]);
757 assert_eq!(list.first(pool), Some(i1));
758 assert_eq!(list.get(0, pool), Some(i1));
759 assert_eq!(list.get(1, pool), Some(i2));
760 assert_eq!(list.get(2, pool), None);
761
762 assert_eq!(list.push(i3, pool), 2);
763 assert_eq!(list.len(pool), 3);
764 assert!(!list.is_empty());
765 assert_eq!(list.as_slice(pool), &[i1, i2, i3]);
766 assert_eq!(list.first(pool), Some(i1));
767 assert_eq!(list.get(0, pool), Some(i1));
768 assert_eq!(list.get(1, pool), Some(i2));
769 assert_eq!(list.get(2, pool), Some(i3));
770 assert_eq!(list.get(3, pool), None);
771
772 assert_eq!(list.push(i4, pool), 3);
774 assert_eq!(list.len(pool), 4);
775 assert!(!list.is_empty());
776 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4]);
777 assert_eq!(list.first(pool), Some(i1));
778 assert_eq!(list.get(0, pool), Some(i1));
779 assert_eq!(list.get(1, pool), Some(i2));
780 assert_eq!(list.get(2, pool), Some(i3));
781 assert_eq!(list.get(3, pool), Some(i4));
782 assert_eq!(list.get(4, pool), None);
783
784 list.extend([i1, i1, i2, i2, i3, i3, i4, i4].iter().cloned(), pool);
785 assert_eq!(list.len(pool), 12);
786 assert_eq!(
787 list.as_slice(pool),
788 &[i1, i2, i3, i4, i1, i1, i2, i2, i3, i3, i4, i4]
789 );
790
791 let list2 = EntityList::from_iter([i1, i1, i2, i2, i3, i3, i4, i4].iter().cloned(), pool);
792 assert_eq!(list2.len(pool), 8);
793 assert_eq!(list2.as_slice(pool), &[i1, i1, i2, i2, i3, i3, i4, i4]);
794 }
795
796 #[test]
797 fn insert_remove() {
798 let pool = &mut ListPool::<Inst>::new();
799 let mut list = EntityList::<Inst>::default();
800
801 let i1 = Inst::new(1);
802 let i2 = Inst::new(2);
803 let i3 = Inst::new(3);
804 let i4 = Inst::new(4);
805
806 list.insert(0, i4, pool);
807 assert_eq!(list.as_slice(pool), &[i4]);
808
809 list.insert(0, i3, pool);
810 assert_eq!(list.as_slice(pool), &[i3, i4]);
811
812 list.insert(2, i2, pool);
813 assert_eq!(list.as_slice(pool), &[i3, i4, i2]);
814
815 list.insert(2, i1, pool);
816 assert_eq!(list.as_slice(pool), &[i3, i4, i1, i2]);
817
818 list.remove(3, pool);
819 assert_eq!(list.as_slice(pool), &[i3, i4, i1]);
820
821 list.remove(2, pool);
822 assert_eq!(list.as_slice(pool), &[i3, i4]);
823
824 list.remove(0, pool);
825 assert_eq!(list.as_slice(pool), &[i4]);
826
827 list.remove(0, pool);
828 assert_eq!(list.as_slice(pool), &[]);
829 assert!(list.is_empty());
830 }
831
832 #[test]
833 fn growing() {
834 let pool = &mut ListPool::<Inst>::new();
835 let mut list = EntityList::<Inst>::default();
836
837 let i1 = Inst::new(1);
838 let i2 = Inst::new(2);
839 let i3 = Inst::new(3);
840 let i4 = Inst::new(4);
841
842 list.grow_at(0, 0, pool);
844 assert_eq!(list.len(pool), 0);
845 assert!(list.is_empty());
846
847 list.grow_at(0, 2, pool);
848 assert_eq!(list.len(pool), 2);
849
850 list.as_mut_slice(pool).copy_from_slice(&[i2, i3]);
851
852 list.grow_at(1, 0, pool);
853 assert_eq!(list.as_slice(pool), &[i2, i3]);
854
855 list.grow_at(1, 1, pool);
856 list.as_mut_slice(pool)[1] = i1;
857 assert_eq!(list.as_slice(pool), &[i2, i1, i3]);
858
859 list.grow_at(3, 0, pool);
861 assert_eq!(list.as_slice(pool), &[i2, i1, i3]);
862
863 list.grow_at(3, 1, pool);
865 list.as_mut_slice(pool)[3] = i4;
866 assert_eq!(list.as_slice(pool), &[i2, i1, i3, i4]);
867 }
868
869 #[test]
870 fn deep_clone() {
871 let pool = &mut ListPool::<Inst>::new();
872
873 let i1 = Inst::new(1);
874 let i2 = Inst::new(2);
875 let i3 = Inst::new(3);
876 let i4 = Inst::new(4);
877
878 let mut list1 = EntityList::from_slice(&[i1, i2, i3], pool);
879 let list2 = list1.deep_clone(pool);
880 assert_eq!(list1.as_slice(pool), &[i1, i2, i3]);
881 assert_eq!(list2.as_slice(pool), &[i1, i2, i3]);
882
883 list1.as_mut_slice(pool)[0] = i4;
884 assert_eq!(list1.as_slice(pool), &[i4, i2, i3]);
885 assert_eq!(list2.as_slice(pool), &[i1, i2, i3]);
886 }
887
888 #[test]
889 fn truncate() {
890 let pool = &mut ListPool::<Inst>::new();
891
892 let i1 = Inst::new(1);
893 let i2 = Inst::new(2);
894 let i3 = Inst::new(3);
895 let i4 = Inst::new(4);
896
897 let mut list = EntityList::from_slice(&[i1, i2, i3, i4, i1, i2, i3, i4], pool);
898 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4, i1, i2, i3, i4]);
899 list.truncate(6, pool);
900 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4, i1, i2]);
901 list.truncate(9, pool);
902 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4, i1, i2]);
903 list.truncate(2, pool);
904 assert_eq!(list.as_slice(pool), &[i1, i2]);
905 list.truncate(0, pool);
906 assert!(list.is_empty());
907 }
908
909 #[test]
910 fn copy_from() {
911 let pool = &mut ListPool::<Inst>::new();
912
913 let i1 = Inst::new(1);
914 let i2 = Inst::new(2);
915 let i3 = Inst::new(3);
916 let i4 = Inst::new(4);
917
918 let mut list = EntityList::from_slice(&[i1, i2, i3, i4], pool);
919 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4]);
920 let list2 = EntityList::from_slice(&[i4, i3, i2, i1], pool);
921 assert_eq!(list2.as_slice(pool), &[i4, i3, i2, i1]);
922 list.copy_from(&list2, 0..0, 0, pool);
923 assert_eq!(list.as_slice(pool), &[i1, i2, i3, i4]);
924 list.copy_from(&list2, 0..4, 0, pool);
925 assert_eq!(list.as_slice(pool), &[i4, i3, i2, i1, i1, i2, i3, i4]);
926 }
927
928 #[test]
929 #[should_panic]
930 fn copy_from_self() {
931 let pool = &mut ListPool::<Inst>::new();
932
933 let i1 = Inst::new(1);
934 let i2 = Inst::new(2);
935 let i3 = Inst::new(3);
936 let i4 = Inst::new(4);
937
938 let mut list = EntityList::from_slice(&[i4, i3, i2, i1, i1, i2, i3, i4], pool);
939 let list_again = list;
940 assert_eq!(list.as_slice(pool), &[i4, i3, i2, i1, i1, i2, i3, i4]);
941 list.copy_from(&list_again, 0..=1, 8, pool);
943 assert_eq!(
944 list.as_slice(pool),
945 &[i4, i3, i2, i1, i1, i2, i3, i4, i4, i3]
946 );
947 list.copy_from(&list_again, .., 7, pool);
948 assert_eq!(
949 list.as_slice(pool),
950 &[i4, i3, i2, i1, i1, i2, i4, i3, i2, i1, i1, i2, i3, i4, i4, i3, i3, i4, i4, i3]
951 )
952 }
953}