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