1#![allow(clippy::unneeded_field_pattern)]
24
25use crate::{
26 inspect::{Inspect, PropertyInfo},
27 visitor::{Visit, VisitResult, Visitor},
28};
29use std::{
30 any::TypeId,
31 fmt::{Debug, Display, Formatter},
32 future::Future,
33 hash::{Hash, Hasher},
34 iter::FromIterator,
35 marker::PhantomData,
36 ops::{Index, IndexMut},
37};
38
39const INVALID_GENERATION: u32 = 0;
40
41#[derive(Debug)]
46pub struct Pool<T: Sized> {
47 records: Vec<PoolRecord<T>>,
48 free_stack: Vec<u32>,
49}
50
51impl<T: PartialEq> PartialEq for Pool<T> {
52 fn eq(&self, other: &Self) -> bool {
53 self.records == other.records
54 }
55}
56
57pub struct Handle<T> {
61 index: u32,
63 generation: u32,
66 type_marker: PhantomData<T>,
68}
69
70impl<T: 'static> Inspect for Handle<T> {
71 fn properties(&self) -> Vec<PropertyInfo<'_>> {
72 vec![
73 PropertyInfo {
74 owner_type_id: TypeId::of::<Self>(),
75 name: "index",
76 display_name: "Index",
77 value: &self.index,
78 read_only: true,
79 min_value: None,
80 max_value: None,
81 step: None,
82 precision: None,
83 description: "Index of an object in a pool.".to_string(),
84 },
85 PropertyInfo {
86 owner_type_id: TypeId::of::<Self>(),
87 name: "generation",
88 display_name: "Generation",
89 value: &self.generation,
90 read_only: true,
91 min_value: None,
92 max_value: None,
93 step: None,
94 precision: None,
95 description: "Generation of an object in a pool.".to_string(),
96 },
97 ]
98 }
99}
100
101unsafe impl<T> Send for Handle<T> {}
102unsafe impl<T> Sync for Handle<T> {}
103
104impl<T> Display for Handle<T> {
105 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
106 write!(f, "{}:{}", self.index, self.generation)
107 }
108}
109
110#[derive(Copy, Clone, Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Inspect)]
112pub struct ErasedHandle {
113 #[inspect(read_only)]
115 index: u32,
116 #[inspect(read_only)]
119 generation: u32,
120}
121
122impl Default for ErasedHandle {
123 fn default() -> Self {
124 Self::none()
125 }
126}
127
128impl<T> From<ErasedHandle> for Handle<T> {
129 fn from(erased_handle: ErasedHandle) -> Self {
130 Handle {
131 index: erased_handle.index,
132 generation: erased_handle.generation,
133 type_marker: PhantomData,
134 }
135 }
136}
137
138impl<T> From<Handle<T>> for ErasedHandle {
139 fn from(h: Handle<T>) -> Self {
140 Self {
141 index: h.index,
142 generation: h.generation,
143 }
144 }
145}
146
147impl Visit for ErasedHandle {
148 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
149 visitor.enter_region(name)?;
150
151 self.index.visit("Index", visitor)?;
152 self.generation.visit("Generation", visitor)?;
153
154 visitor.leave_region()
155 }
156}
157
158impl ErasedHandle {
159 pub fn none() -> Self {
160 Self {
161 index: 0,
162 generation: INVALID_GENERATION,
163 }
164 }
165
166 pub fn new(index: u32, generation: u32) -> Self {
167 Self { index, generation }
168 }
169
170 #[inline(always)]
171 pub fn is_some(&self) -> bool {
172 self.generation != INVALID_GENERATION
173 }
174
175 #[inline(always)]
176 pub fn is_none(&self) -> bool {
177 !self.is_some()
178 }
179
180 #[inline(always)]
181 pub fn index(self) -> u32 {
182 self.index
183 }
184
185 #[inline(always)]
186 pub fn generation(self) -> u32 {
187 self.generation
188 }
189}
190
191impl<T> Visit for Handle<T> {
192 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
193 visitor.enter_region(name)?;
194
195 self.index.visit("Index", visitor)?;
196 self.generation.visit("Generation", visitor)?;
197
198 visitor.leave_region()
199 }
200}
201
202impl<T> Default for Handle<T> {
203 fn default() -> Self {
204 Self::NONE
205 }
206}
207
208impl<T> Debug for Handle<T> {
209 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
210 write!(f, "[Idx: {}; Gen: {}]", self.index, self.generation)
211 }
212}
213
214#[derive(Debug)]
215struct PoolRecord<T: Sized> {
216 generation: u32,
220 payload: Option<T>,
222}
223
224impl<T: PartialEq> PartialEq for PoolRecord<T> {
225 fn eq(&self, other: &Self) -> bool {
226 self.generation == other.generation && self.payload == other.payload
227 }
228}
229
230impl<T> Default for PoolRecord<T> {
231 fn default() -> Self {
232 Self {
233 generation: INVALID_GENERATION,
234 payload: None,
235 }
236 }
237}
238
239impl<T> Visit for PoolRecord<T>
240where
241 T: Visit + Default + 'static,
242{
243 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
244 visitor.enter_region(name)?;
245
246 self.generation.visit("Generation", visitor)?;
247 self.payload.visit("Payload", visitor)?;
248
249 visitor.leave_region()
250 }
251}
252
253impl<T> Clone for Handle<T> {
254 fn clone(&self) -> Handle<T> {
255 Handle {
256 index: self.index,
257 generation: self.generation,
258 type_marker: PhantomData,
259 }
260 }
261}
262
263impl<T> Copy for Handle<T> {}
264
265impl<T> Eq for Handle<T> {}
266
267impl<T> PartialEq for Handle<T> {
268 fn eq(&self, other: &Handle<T>) -> bool {
269 self.generation == other.generation && self.index == other.index
270 }
271}
272
273impl<T> Visit for Pool<T>
274where
275 T: Default + Visit + 'static,
276{
277 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
278 visitor.enter_region(name)?;
279 self.records.visit("Records", visitor)?;
280 self.free_stack.visit("FreeStack", visitor)?;
281 visitor.leave_region()
282 }
283}
284
285impl<T> Hash for Handle<T> {
286 fn hash<H: Hasher>(&self, state: &mut H) {
287 self.index.hash(state);
288 self.generation.hash(state);
289 }
290}
291
292impl<T> Handle<T> {
293 pub const NONE: Handle<T> = Handle {
294 index: 0,
295 generation: INVALID_GENERATION,
296 type_marker: PhantomData,
297 };
298
299 #[inline(always)]
300 pub fn is_none(self) -> bool {
301 self.index == 0 && self.generation == INVALID_GENERATION
302 }
303
304 #[inline(always)]
305 pub fn is_some(self) -> bool {
306 !self.is_none()
307 }
308
309 #[inline(always)]
310 pub fn index(self) -> u32 {
311 self.index
312 }
313
314 #[inline(always)]
315 pub fn generation(self) -> u32 {
316 self.generation
317 }
318
319 #[inline(always)]
320 pub fn new(index: u32, generation: u32) -> Self {
321 Handle {
322 index,
323 generation,
324 type_marker: PhantomData,
325 }
326 }
327}
328
329impl<T> Default for Pool<T> {
330 fn default() -> Self {
331 Self::new()
332 }
333}
334
335#[derive(Debug)]
336pub struct Ticket<T> {
337 index: u32,
338 marker: PhantomData<T>,
339}
340
341impl<T: Clone> Clone for PoolRecord<T> {
342 fn clone(&self) -> Self {
343 Self {
344 generation: self.generation,
345 payload: self.payload.clone(),
346 }
347 }
348}
349
350impl<T: Clone> Clone for Pool<T> {
351 fn clone(&self) -> Self {
352 Self {
353 records: self.records.clone(),
354 free_stack: self.free_stack.clone(),
355 }
356 }
357}
358
359impl<T> Pool<T> {
360 #[inline]
361 pub fn new() -> Self {
362 Pool {
363 records: Vec::new(),
364 free_stack: Vec::new(),
365 }
366 }
367
368 #[inline]
369 pub fn with_capacity(capacity: u32) -> Self {
370 let capacity = usize::try_from(capacity).expect("capacity overflowed usize");
371 Pool {
372 records: Vec::with_capacity(capacity),
373 free_stack: Vec::new(),
374 }
375 }
376
377 fn records_len(&self) -> u32 {
378 u32::try_from(self.records.len()).expect("Number of records overflowed u32")
379 }
380
381 fn records_get(&self, index: u32) -> Option<&PoolRecord<T>> {
382 let index = usize::try_from(index).expect("Index overflowed usize");
383 self.records.get(index)
384 }
385
386 fn records_get_mut(&mut self, index: u32) -> Option<&mut PoolRecord<T>> {
387 let index = usize::try_from(index).expect("Index overflowed usize");
388 self.records.get_mut(index)
389 }
390
391 #[inline]
392 #[must_use]
393 pub fn spawn(&mut self, payload: T) -> Handle<T> {
394 self.spawn_with(|_| payload)
395 }
396
397 #[inline]
412 pub fn spawn_at(&mut self, index: u32, payload: T) -> Result<Handle<T>, T> {
413 self.spawn_at_internal(index, INVALID_GENERATION, payload)
414 }
415
416 pub fn spawn_at_handle(&mut self, handle: Handle<T>, payload: T) -> Result<Handle<T>, T> {
431 self.spawn_at_internal(handle.index, handle.generation, payload)
432 }
433
434 fn spawn_at_internal(
435 &mut self,
436 index: u32,
437 desired_generation: u32,
438 payload: T,
439 ) -> Result<Handle<T>, T> {
440 let index_usize = usize::try_from(index).expect("index overflowed usize");
441 match self.records.get_mut(index_usize) {
442 Some(record) => match record.payload {
443 Some(_) => Err(payload),
444 None => {
445 let position = self
446 .free_stack
447 .iter()
448 .rposition(|i| *i == index)
449 .expect("free_stack must contain the index of the empty record (most likely attempting to spawn at a reserved index)!");
450
451 self.free_stack.remove(position);
452
453 let generation = if desired_generation == INVALID_GENERATION {
454 record.generation + 1
455 } else {
456 desired_generation
457 };
458
459 record.generation = generation;
460 record.payload = Some(payload);
461
462 Ok(Handle::new(index, generation))
463 }
464 },
465 None => {
466 for i in self.records_len()..index {
468 self.records.push(PoolRecord {
469 generation: 1,
470 payload: None,
471 });
472 self.free_stack.push(i);
473 }
474
475 let generation = if desired_generation == INVALID_GENERATION {
476 1
477 } else {
478 desired_generation
479 };
480
481 self.records.push(PoolRecord {
482 generation,
483 payload: Some(payload),
484 });
485
486 Ok(Handle::new(index, generation))
487 }
488 }
489 }
490
491 #[inline]
492 #[must_use]
493 pub fn spawn_with<F: FnOnce(Handle<T>) -> T>(&mut self, callback: F) -> Handle<T> {
496 if let Some(free_index) = self.free_stack.pop() {
497 let record = self
498 .records_get_mut(free_index)
499 .expect("free stack contained invalid index");
500
501 if record.payload.is_some() {
502 panic!(
503 "Attempt to spawn an object at pool record with payload! Record index is {}",
504 free_index
505 );
506 }
507
508 let generation = record.generation + 1;
509 let handle = Handle {
510 index: free_index,
511 generation,
512 type_marker: PhantomData,
513 };
514
515 let payload = callback(handle);
516
517 record.generation = generation;
518 record.payload.replace(payload);
519 handle
520 } else {
521 let generation = 1;
523
524 let handle = Handle {
525 index: self.records.len() as u32,
526 generation,
527 type_marker: PhantomData,
528 };
529
530 let payload = callback(handle);
531
532 let record = PoolRecord {
533 generation,
534 payload: Some(payload),
535 };
536
537 self.records.push(record);
538
539 handle
540 }
541 }
542
543 #[inline]
544 pub async fn spawn_with_async<F, Fut>(&mut self, callback: F) -> Handle<T>
547 where
548 F: FnOnce(Handle<T>) -> Fut,
549 Fut: Future<Output = T>,
550 {
551 if let Some(free_index) = self.free_stack.pop() {
552 let record = self
553 .records_get_mut(free_index)
554 .expect("free stack contained invalid index");
555
556 if record.payload.is_some() {
557 panic!(
558 "Attempt to spawn an object at pool record with payload! Record index is {}",
559 free_index
560 );
561 }
562
563 let generation = record.generation + 1;
564 let handle = Handle {
565 index: free_index,
566 generation,
567 type_marker: PhantomData,
568 };
569
570 let payload = callback(handle).await;
571
572 record.generation = generation;
573 record.payload.replace(payload);
574 handle
575 } else {
576 let generation = 1;
578
579 let handle = Handle {
580 index: self.records.len() as u32,
581 generation,
582 type_marker: PhantomData,
583 };
584
585 let payload = callback(handle).await;
586
587 let record = PoolRecord {
588 generation,
589 payload: Some(payload),
590 };
591
592 self.records.push(record);
593
594 handle
595 }
596 }
597
598 #[inline]
606 #[must_use]
607 pub fn borrow(&self, handle: Handle<T>) -> &T {
608 if let Some(record) = self.records_get(handle.index) {
609 if record.generation == handle.generation {
610 if let Some(ref payload) = record.payload {
611 payload
612 } else {
613 panic!("Attempt to borrow destroyed object at {:?} handle.", handle);
614 }
615 } else {
616 panic!(
617 "Attempt to use dangling handle {:?}. Record has generation {}!",
618 handle, record.generation
619 );
620 }
621 } else {
622 panic!(
623 "Attempt to borrow object using out-of-bounds handle {:?}! Record count is {}",
624 handle,
625 self.records.len()
626 );
627 }
628 }
629
630 #[inline]
648 #[must_use]
649 pub fn borrow_mut(&mut self, handle: Handle<T>) -> &mut T {
650 let record_count = self.records.len();
651 if let Some(record) = self.records_get_mut(handle.index) {
652 if record.generation == handle.generation {
653 if let Some(ref mut payload) = record.payload {
654 payload
655 } else {
656 panic!("Attempt to borrow destroyed object at {:?} handle.", handle);
657 }
658 } else {
659 panic!("Attempt to borrow object using dangling handle {:?}. Record has {} generation!", handle, record.generation);
660 }
661 } else {
662 panic!(
663 "Attempt to borrow object using out-of-bounds handle {:?}! Record count is {}",
664 handle, record_count
665 );
666 }
667 }
668
669 #[inline]
675 #[must_use]
676 pub fn try_borrow(&self, handle: Handle<T>) -> Option<&T> {
677 self.records_get(handle.index).and_then(|r| {
678 if r.generation == handle.generation {
679 r.payload.as_ref()
680 } else {
681 None
682 }
683 })
684 }
685
686 #[inline]
692 #[must_use]
693 pub fn try_borrow_mut(&mut self, handle: Handle<T>) -> Option<&mut T> {
694 self.records_get_mut(handle.index).and_then(|r| {
695 if r.generation == handle.generation {
696 r.payload.as_mut()
697 } else {
698 None
699 }
700 })
701 }
702
703 #[inline]
723 #[must_use = "Handle set must not be ignored"]
724 pub fn borrow_two_mut(&mut self, handles: (Handle<T>, Handle<T>)) -> (&mut T, &mut T) {
725 assert_ne!(handles.0.index, handles.1.index);
727 unsafe {
728 let this = self as *mut Self;
729 ((*this).borrow_mut(handles.0), (*this).borrow_mut(handles.1))
730 }
731 }
732
733 #[inline]
755 #[must_use = "Handle set must not be ignored"]
756 pub fn borrow_three_mut(
757 &mut self,
758 handles: (Handle<T>, Handle<T>, Handle<T>),
759 ) -> (&mut T, &mut T, &mut T) {
760 assert_ne!(handles.0.index, handles.1.index);
762 assert_ne!(handles.0.index, handles.2.index);
763 assert_ne!(handles.1.index, handles.2.index);
764 unsafe {
765 let this = self as *mut Self;
766 (
767 (*this).borrow_mut(handles.0),
768 (*this).borrow_mut(handles.1),
769 (*this).borrow_mut(handles.2),
770 )
771 }
772 }
773
774 #[inline]
798 #[must_use = "Handle set must not be ignored"]
799 pub fn borrow_four_mut(
800 &mut self,
801 handles: (Handle<T>, Handle<T>, Handle<T>, Handle<T>),
802 ) -> (&mut T, &mut T, &mut T, &mut T) {
803 assert_ne!(handles.0.index, handles.1.index);
806 assert_ne!(handles.0.index, handles.2.index);
807 assert_ne!(handles.0.index, handles.3.index);
808 assert_ne!(handles.1.index, handles.2.index);
809 assert_ne!(handles.1.index, handles.3.index);
810 assert_ne!(handles.2.index, handles.3.index);
811 unsafe {
812 let this = self as *mut Self;
813 (
814 (*this).borrow_mut(handles.0),
815 (*this).borrow_mut(handles.1),
816 (*this).borrow_mut(handles.2),
817 (*this).borrow_mut(handles.3),
818 )
819 }
820 }
821
822 pub fn try_borrow_dependant_mut<F>(
824 &mut self,
825 handle: Handle<T>,
826 func: F,
827 ) -> (Option<&mut T>, Option<&mut T>)
828 where
829 F: FnOnce(&T) -> Handle<T>,
830 {
831 let this = unsafe { &mut *(self as *mut Pool<T>) };
832 let first = self.try_borrow_mut(handle);
833 if let Some(first_object) = first.as_ref() {
834 let second_handle = func(first_object);
835 if second_handle != handle {
836 return (first, this.try_borrow_mut(second_handle));
837 }
838 }
839
840 (first, None)
841 }
842
843 #[inline]
849 pub fn free(&mut self, handle: Handle<T>) -> T {
850 let index = usize::try_from(handle.index).expect("index overflowed usize");
851 if let Some(record) = self.records.get_mut(index) {
852 if record.generation == handle.generation {
853 self.free_stack.push(handle.index);
855 if let Some(payload) = record.payload.take() {
857 payload
858 } else {
859 panic!("Attempt to double free object at handle {:?}!", handle);
860 }
861 } else {
862 panic!(
863 "Attempt to free object using dangling handle {:?}! Record generation is {}",
864 handle, record.generation
865 );
866 }
867 } else {
868 panic!("Attempt to free destroyed object using out-of-bounds handle {:?}! Record count is {}", handle, self.records.len());
869 }
870 }
871
872 #[inline]
893 pub fn take_reserve(&mut self, handle: Handle<T>) -> (Ticket<T>, T) {
894 if let Some(record) = self.records_get_mut(handle.index) {
895 if record.generation == handle.generation {
896 if let Some(payload) = record.payload.take() {
897 let ticket = Ticket {
898 index: handle.index,
899 marker: PhantomData,
900 };
901 (ticket, payload)
902 } else {
903 panic!(
904 "Attempt to take already taken object at handle {:?}!",
905 handle
906 );
907 }
908 } else {
909 panic!(
910 "Attempt to take object using dangling handle {:?}! Record generation is {}",
911 handle, record.generation
912 );
913 }
914 } else {
915 panic!("Attempt to take destroyed object using out-of-bounds handle {:?}! Record count is {}", handle, self.records.len());
916 }
917 }
918
919 #[inline]
923 pub fn try_take_reserve(&mut self, handle: Handle<T>) -> Option<(Ticket<T>, T)> {
924 if let Some(record) = self.records_get_mut(handle.index) {
925 if record.generation == handle.generation {
926 if let Some(payload) = record.payload.take() {
927 let ticket = Ticket {
928 index: handle.index,
929 marker: PhantomData,
930 };
931 Some((ticket, payload))
932 } else {
933 None
934 }
935 } else {
936 None
937 }
938 } else {
939 None
940 }
941 }
942
943 pub fn put_back(&mut self, ticket: Ticket<T>, value: T) -> Handle<T> {
948 let record = self
949 .records_get_mut(ticket.index)
950 .expect("Ticket index was invalid");
951 let old = record.payload.replace(value);
952 assert!(old.is_none());
953 Handle::new(ticket.index, record.generation)
954 }
955
956 pub fn forget_ticket(&mut self, ticket: Ticket<T>) {
960 self.free_stack.push(ticket.index);
961 }
962
963 #[inline]
965 #[must_use]
966 pub fn get_capacity(&self) -> u32 {
967 u32::try_from(self.records.len()).expect("records.len() overflowed u32")
968 }
969
970 #[inline]
978 pub fn clear(&mut self) {
979 self.records.clear();
980 self.free_stack.clear();
981 }
982
983 #[inline]
984 #[must_use]
985 pub fn at_mut(&mut self, n: u32) -> Option<&mut T> {
986 self.records_get_mut(n).and_then(|rec| rec.payload.as_mut())
987 }
988
989 #[inline]
990 #[must_use]
991 pub fn at(&self, n: u32) -> Option<&T> {
992 self.records_get(n).and_then(|rec| rec.payload.as_ref())
993 }
994
995 #[inline]
996 #[must_use]
997 pub fn handle_from_index(&self, n: u32) -> Handle<T> {
998 if let Some(record) = self.records_get(n) {
999 if record.generation != INVALID_GENERATION {
1000 return Handle::new(n, record.generation);
1001 }
1002 }
1003 Handle::NONE
1004 }
1005
1006 #[inline]
1027 #[must_use]
1028 pub fn alive_count(&self) -> u32 {
1029 let cnt = self.iter().count();
1030 u32::try_from(cnt).expect("alive_count overflowed u32")
1031 }
1032
1033 pub fn total_count(&self) -> u32 {
1044 let free = u32::try_from(self.free_stack.len()).expect("free stack length overflowed u32");
1045 self.records_len() - free
1046 }
1047
1048 #[inline]
1049 pub fn replace(&mut self, handle: Handle<T>, payload: T) -> Option<T> {
1050 let index_usize = usize::try_from(handle.index).expect("index overflowed usize");
1051 if let Some(record) = self.records.get_mut(index_usize) {
1052 if record.generation == handle.generation {
1053 self.free_stack.retain(|i| *i != handle.index);
1054
1055 record.payload.replace(payload)
1056 } else {
1057 panic!("Attempt to replace object in pool using dangling handle! Handle is {:?}, but pool record has {} generation", handle, record.generation);
1058 }
1059 } else {
1060 None
1061 }
1062 }
1063
1064 #[inline]
1075 pub fn is_valid_handle(&self, handle: Handle<T>) -> bool {
1076 if let Some(record) = self.records_get(handle.index) {
1077 record.payload.is_some() && record.generation == handle.generation
1078 } else {
1079 false
1080 }
1081 }
1082
1083 #[must_use]
1097 pub fn iter(&self) -> PoolIterator<T> {
1098 unsafe {
1099 PoolIterator {
1100 ptr: self.records.as_ptr(),
1101 end: self.records.as_ptr().add(self.records.len()),
1102 marker: PhantomData,
1103 }
1104 }
1105 }
1106
1107 pub fn pair_iter(&self) -> PoolPairIterator<T> {
1111 PoolPairIterator {
1112 pool: self,
1113 current: 0,
1114 }
1115 }
1116
1117 #[must_use]
1132 pub fn iter_mut(&mut self) -> PoolIteratorMut<T> {
1133 unsafe {
1134 PoolIteratorMut {
1135 ptr: self.records.as_mut_ptr(),
1136 end: self.records.as_mut_ptr().add(self.records.len()),
1137 marker: PhantomData,
1138 }
1139 }
1140 }
1141
1142 pub fn pair_iter_mut(&mut self) -> PoolPairIteratorMut<T> {
1146 unsafe {
1147 PoolPairIteratorMut {
1148 current: 0,
1149 ptr: self.records.as_mut_ptr(),
1150 end: self.records.as_mut_ptr().add(self.records.len()),
1151 marker: PhantomData,
1152 }
1153 }
1154 }
1155
1156 pub fn retain<F>(&mut self, mut pred: F)
1159 where
1160 F: FnMut(&T) -> bool,
1161 {
1162 for (i, record) in self.records.iter_mut().enumerate() {
1163 if record.generation == INVALID_GENERATION {
1164 continue;
1165 }
1166
1167 let retain = if let Some(payload) = record.payload.as_ref() {
1168 pred(payload)
1169 } else {
1170 continue;
1171 };
1172
1173 if !retain {
1174 self.free_stack.push(i as u32);
1175 record.payload.take(); }
1177 }
1178 }
1179
1180 fn end(&self) -> *const PoolRecord<T> {
1181 unsafe { self.records.as_ptr().add(self.records.len()) }
1182 }
1183
1184 fn begin(&self) -> *const PoolRecord<T> {
1185 self.records.as_ptr()
1186 }
1187
1188 pub fn handle_of(&self, ptr: &T) -> Handle<T> {
1189 let begin = self.begin() as usize;
1190 let end = self.end() as usize;
1191 let val = ptr as *const T as usize;
1192 if val >= begin && val < end {
1193 let record_size = std::mem::size_of::<PoolRecord<T>>();
1194 let record_location = (val - offset_of!(PoolRecord<T>, payload)) - begin;
1195 if record_location % record_size == 0 {
1196 let index = record_location / record_size;
1197 let index = u32::try_from(index).expect("Index overflowed u32");
1198 return self.handle_from_index(index);
1199 }
1200 }
1201 Handle::NONE
1202 }
1203}
1204
1205impl<T> FromIterator<T> for Pool<T> {
1206 fn from_iter<C: IntoIterator<Item = T>>(iter: C) -> Self {
1207 let iter = iter.into_iter();
1208 let (lower_bound, upper_bound) = iter.size_hint();
1209 let lower_bound = u32::try_from(lower_bound).expect("lower_bound overflowed u32");
1210 let upper_bound =
1211 upper_bound.map(|b| u32::try_from(b).expect("upper_bound overflowed u32"));
1212 let mut pool = Self::with_capacity(upper_bound.unwrap_or(lower_bound));
1213 for v in iter {
1214 let _ = pool.spawn(v);
1215 }
1216 pool
1217 }
1218}
1219
1220impl<T> Index<Handle<T>> for Pool<T> {
1221 type Output = T;
1222
1223 fn index(&self, index: Handle<T>) -> &Self::Output {
1224 self.borrow(index)
1225 }
1226}
1227
1228impl<T> IndexMut<Handle<T>> for Pool<T> {
1229 fn index_mut(&mut self, index: Handle<T>) -> &mut Self::Output {
1230 self.borrow_mut(index)
1231 }
1232}
1233
1234impl<'a, T> IntoIterator for &'a Pool<T> {
1235 type Item = &'a T;
1236 type IntoIter = PoolIterator<'a, T>;
1237
1238 fn into_iter(self) -> Self::IntoIter {
1239 self.iter()
1240 }
1241}
1242
1243impl<'a, T> IntoIterator for &'a mut Pool<T> {
1244 type Item = &'a mut T;
1245 type IntoIter = PoolIteratorMut<'a, T>;
1246
1247 fn into_iter(self) -> Self::IntoIter {
1248 self.iter_mut()
1249 }
1250}
1251
1252pub struct PoolIterator<'a, T> {
1253 ptr: *const PoolRecord<T>,
1254 end: *const PoolRecord<T>,
1255 marker: PhantomData<&'a T>,
1256}
1257
1258impl<'a, T> Iterator for PoolIterator<'a, T> {
1259 type Item = &'a T;
1260
1261 fn next(&mut self) -> Option<Self::Item> {
1262 unsafe {
1263 while self.ptr != self.end {
1264 let current = &*self.ptr;
1265 if let Some(ref payload) = current.payload {
1266 self.ptr = self.ptr.offset(1);
1267 return Some(payload);
1268 }
1269 self.ptr = self.ptr.offset(1);
1270 }
1271
1272 None
1273 }
1274 }
1275}
1276
1277pub struct PoolPairIterator<'a, T> {
1278 pool: &'a Pool<T>,
1279 current: usize,
1280}
1281
1282impl<'a, T> Iterator for PoolPairIterator<'a, T> {
1283 type Item = (Handle<T>, &'a T);
1284
1285 fn next(&mut self) -> Option<Self::Item> {
1286 loop {
1287 match self.pool.records.get(self.current) {
1288 Some(record) => {
1289 if let Some(payload) = &record.payload {
1290 let handle = Handle::new(self.current as u32, record.generation);
1291 self.current += 1;
1292 return Some((handle, payload));
1293 }
1294 self.current += 1;
1295 }
1296 None => return None,
1297 }
1298 }
1299 }
1300}
1301
1302pub struct PoolIteratorMut<'a, T> {
1303 ptr: *mut PoolRecord<T>,
1304 end: *mut PoolRecord<T>,
1305 marker: PhantomData<&'a mut T>,
1306}
1307
1308impl<'a, T> Iterator for PoolIteratorMut<'a, T> {
1309 type Item = &'a mut T;
1310
1311 fn next(&mut self) -> Option<Self::Item> {
1312 unsafe {
1313 while self.ptr != self.end {
1314 let current = &mut *self.ptr;
1315 if let Some(ref mut payload) = current.payload {
1316 self.ptr = self.ptr.offset(1);
1317 return Some(payload);
1318 }
1319 self.ptr = self.ptr.offset(1);
1320 }
1321
1322 None
1323 }
1324 }
1325}
1326
1327pub struct PoolPairIteratorMut<'a, T> {
1328 ptr: *mut PoolRecord<T>,
1329 end: *mut PoolRecord<T>,
1330 marker: PhantomData<&'a mut T>,
1331 current: usize,
1332}
1333
1334impl<'a, T> Iterator for PoolPairIteratorMut<'a, T> {
1335 type Item = (Handle<T>, &'a mut T);
1336
1337 fn next(&mut self) -> Option<Self::Item> {
1338 unsafe {
1339 while self.ptr != self.end {
1340 let current = &mut *self.ptr;
1341 if let Some(ref mut payload) = current.payload {
1342 let handle = Handle::new(self.current as u32, current.generation);
1343 self.ptr = self.ptr.offset(1);
1344 self.current += 1;
1345 return Some((handle, payload));
1346 }
1347 self.ptr = self.ptr.offset(1);
1348 self.current += 1;
1349 }
1350
1351 None
1352 }
1353 }
1354}
1355
1356#[cfg(test)]
1357mod test {
1358 use crate::pool::{Handle, Pool, INVALID_GENERATION};
1359
1360 #[test]
1361 fn pool_sanity_tests() {
1362 let mut pool: Pool<String> = Pool::new();
1363 let foobar_handle = pool.spawn(String::from("Foobar"));
1364 assert_eq!(foobar_handle.index, 0);
1365 assert_ne!(foobar_handle.generation, INVALID_GENERATION);
1366 let foobar_handle_copy = foobar_handle;
1367 assert_eq!(foobar_handle.index, foobar_handle_copy.index);
1368 assert_eq!(foobar_handle.generation, foobar_handle_copy.generation);
1369 let baz_handle = pool.spawn(String::from("Baz"));
1370 assert_eq!(pool.borrow(foobar_handle), "Foobar");
1371 assert_eq!(pool.borrow(baz_handle), "Baz");
1372 pool.free(foobar_handle);
1373 assert!(!pool.is_valid_handle(foobar_handle_copy));
1374 assert!(pool.is_valid_handle(baz_handle));
1375 let at_foobar_index = pool.spawn(String::from("AtFoobarIndex"));
1376 assert_eq!(at_foobar_index.index, 0);
1377 assert_ne!(at_foobar_index.generation, INVALID_GENERATION);
1378 assert_eq!(pool.borrow(at_foobar_index), "AtFoobarIndex");
1379 let bar_handle = pool.spawn_with(|_handle| String::from("Bar"));
1380 assert_ne!(bar_handle.index, 0);
1381 assert_ne!(bar_handle.generation, INVALID_GENERATION);
1382 assert_eq!(pool.borrow(bar_handle), "Bar");
1383 }
1384
1385 #[test]
1386 fn pool_iterator_mut_test() {
1387 let mut pool: Pool<String> = Pool::new();
1388 let foobar = pool.spawn("Foobar".to_string());
1389 let d = pool.spawn("Foo".to_string());
1390 pool.free(d);
1391 let baz = pool.spawn("Baz".to_string());
1392 for s in pool.iter() {
1393 println!("{}", s);
1394 }
1395 for s in pool.iter_mut() {
1396 println!("{}", s);
1397 }
1398 for s in &pool {
1399 println!("{}", s);
1400 }
1401 for s in &mut pool {
1402 println!("{}", s);
1403 }
1404 pool.free(foobar);
1405 pool.free(baz);
1406 }
1407
1408 #[test]
1409 fn handle_of() {
1410 #[allow(dead_code)]
1411 struct Value {
1412 data: String,
1413 }
1414
1415 let mut pool = Pool::new();
1416 let foobar = pool.spawn(Value {
1417 data: "Foobar".to_string(),
1418 });
1419 let bar = pool.spawn(Value {
1420 data: "Bar".to_string(),
1421 });
1422 let baz = pool.spawn(Value {
1423 data: "Baz".to_string(),
1424 });
1425 assert_eq!(pool.handle_of(pool.borrow(foobar)), foobar);
1426 assert_eq!(pool.handle_of(pool.borrow(bar)), bar);
1427 assert_eq!(pool.handle_of(pool.borrow(baz)), baz);
1428 }
1429
1430 #[test]
1431 fn pool_test_spawn_at() {
1432 let mut pool = Pool::new();
1433
1434 #[derive(Debug, Eq, PartialEq)]
1435 struct Payload;
1436
1437 assert_eq!(pool.spawn_at(2, Payload), Ok(Handle::new(2, 1)));
1438 assert_eq!(pool.spawn_at(2, Payload), Err(Payload));
1439 assert_eq!(pool.records[0].payload, None);
1440 assert_eq!(pool.records[1].payload, None);
1441 assert_ne!(pool.records[2].payload, None);
1442
1443 assert_eq!(pool.spawn_at(2, Payload), Err(Payload));
1444
1445 pool.free(Handle::new(2, 1));
1446
1447 assert_eq!(pool.spawn_at(2, Payload), Ok(Handle::new(2, 2)));
1448
1449 assert_eq!(pool.spawn(Payload), Handle::new(1, 2));
1450 assert_eq!(pool.spawn(Payload), Handle::new(0, 2));
1451 }
1452}