1use std::{
24 slice,
25 fmt,
26};
27
28pub struct Iter<'a, T> {
45 data: &'a Vec<T>,
46 iter: slice::Iter<'a, usize>,
47}
48
49impl<'a, T> Iterator for Iter<'a, T> {
50 type Item = &'a T;
51
52 fn next(&mut self) -> Option<Self::Item> {
53 let offset = self.iter.next()?;
54 unsafe {
55 Some(self.data.get_unchecked(*offset))
56 }
57 }
58}
59
60pub struct IterMut<'a, T> {
62 data: &'a mut Vec<T>,
63 iter: slice::Iter<'a, usize>,
64}
65
66impl<'a, T> Iterator for IterMut<'a, T> {
67 type Item = &'a mut T;
68
69 fn next(&mut self) -> Option<Self::Item> {
70 use std::mem;
71
72 let offset = self.iter.next()?;
73 unsafe {
74 Some(mem::transmute(self.data.get_unchecked_mut(*offset)))
75 }
76 }
77}
78
79#[derive(Eq, Clone, Default)]
81pub struct Pool<T> {
82 data: Vec<T>,
83 offsets: Vec<usize>,
84 alive_ct: usize,
85}
86
87impl<T> Pool<T> {
88 pub unsafe fn spawn_unchecked(&mut self) -> &mut T {
92 let at = self.alive_ct;
93 self.alive_ct += 1;
94 self.get_at_offset_mut(at)
95 }
96
97 #[inline]
101 pub fn spawn(&mut self) -> Option<&mut T> {
102 if self.is_empty() {
103 None
104 } else {
105 Some(unsafe { self.spawn_unchecked() })
106 }
107 }
108
109 pub fn spawn_exact(&mut self, count: usize) -> Vec<&mut T> {
115 use std::mem;
116
117 if count > self.available() {
118 Vec::new()
119 } else {
120 let offsets = &self.offsets[self.alive_ct..self.alive_ct + count];
121 self.alive_ct += count;
122
123 let mut ret = Vec::with_capacity(count);
124 for offset in offsets {
125 ret.push(unsafe {
126 mem::transmute(self.data.get_unchecked_mut(*offset))
127 });
128 }
129 ret
130 }
131 }
132
133 pub fn spawn_some(&mut self, count: usize) -> Vec<&mut T> {
137 use std::cmp;
138 self.spawn_exact(cmp::min(count, self.available()))
139 }
140
141 pub fn reclaim<F: FnMut(&T) -> bool>(&mut self, mut kill_fn: F) {
147 let len = self.alive_ct;
151 let mut del = 0;
152 for i in 0..len {
153 if kill_fn(unsafe { self.get_at_offset(i) }) {
154 del += 1;
155 } else if del > 0 {
156 self.offsets.swap(i, i - del);
157 }
158 }
159 self.alive_ct -= del;
160 }
161
162 pub fn reclaim_unstable<F: FnMut(&T) -> bool>(&mut self, mut kill_fn: F) {
166 let mut len = self.alive_ct;
171 let mut i = 0;
172 while i < len {
173 if kill_fn(unsafe { self.get_at_offset(i) }) {
174 len -= 1;
175 self.offsets.swap(i, len);
176 }
177 i += 1;
178 }
179 self.alive_ct = len;
180 }
181
182 pub fn attach(&mut self, at: usize, obj: T) {
187 if at > self.alive_ct {
188 panic!("index out of bounds");
189 }
190
191 self.offsets.insert(at, self.data.len());
192 self.alive_ct += 1;
193 self.data.push(obj);
194 }
195
196 pub fn detach(&mut self, at: usize) -> T {
200 if at >= self.alive_ct {
201 panic!("index out of bounds");
202 }
203
204 let data_idx = unsafe {
205 self.offset_to_data_idx(at)
206 };
207
208 let ret = self.data.remove(data_idx);
209 self.offsets.remove(at);
210
211 if at != self.alive_ct - 1 {
212 for offset in &mut self.offsets {
213 if *offset > data_idx {
214 *offset -= 1;
215 }
216 }
217 }
218
219 self.alive_ct -= 1;
220 ret
221 }
222
223 #[inline]
228 unsafe fn offset_to_data_idx(&self, at: usize) -> usize {
229 *self.offsets.get_unchecked(at)
230 }
231
232 #[inline]
235 unsafe fn get_at_offset(&self, at: usize) -> &T {
236 self.data.get_unchecked(self.offset_to_data_idx(at))
237 }
238
239 #[inline]
242 unsafe fn get_at_offset_mut(&mut self, at: usize) -> &mut T {
243 let idx = self.offset_to_data_idx(at);
244 self.data.get_unchecked_mut(idx)
245 }
246
247 pub fn get(&self, at: usize) -> Option<&T> {
248 if at < self.alive_ct {
249 Some(unsafe { self.get_at_offset(at) })
250 } else {
251 None
252 }
253 }
254
255 pub fn get_mut(&mut self, at: usize) -> Option<&mut T> {
256 if at < self.alive_ct {
257 Some(unsafe { self.get_at_offset_mut(at) })
258 } else {
259 None
260 }
261 }
262
263 pub fn iter(&self) -> Iter<T> {
266 Iter {
267 data: &self.data,
268 iter: (&self.offsets[..self.alive_ct]).iter(),
269 }
270 }
271
272 pub fn iter_mut(&mut self) -> IterMut<T> {
273 IterMut {
274 data: &mut self.data,
275 iter: (&self.offsets[..self.alive_ct]).iter(),
276 }
277 }
278
279 pub fn sort_the_dead(&mut self) {
283 if self.available() >= 2 {
284 self.offsets[self.alive_ct..].sort_unstable();
285 }
286 }
287
288 #[inline]
290 pub fn is_empty(&self) -> bool {
291 self.available() == 0
292 }
293
294 #[inline]
296 pub fn len(&self) -> usize {
297 self.alive_ct
298 }
299
300 #[inline]
302 pub fn available(&self) -> usize {
303 self.offsets.len() - self.alive_ct
304 }
305
306 #[inline]
308 pub fn capacity(&self) -> usize {
309 self.offsets.len()
310 }
311}
312
313impl<T: Default> Pool<T> {
314 pub fn new(size: usize) -> Self {
317 let mut data: Vec<T> = Vec::with_capacity(size);
318 for _ in 0..size {
319 data.push(T::default());
320 }
321
322 let mut offsets = Vec::with_capacity(size);
323 for i in 0..size {
324 offsets.push(i);
325 }
326
327 Self {
328 data,
329 offsets,
330 alive_ct: 0,
331 }
332 }
333
334 #[inline]
340 pub fn please_spawn(&mut self) -> &mut T {
341 if self.is_empty() {
342 self.offsets.push(self.data.len());
343 self.data.push(T::default());
344 }
345 unsafe { self.spawn_unchecked() }
346 }
347
348 pub fn please_spawn_some(&mut self, count: usize) -> Vec<&mut T> {
354 if count > self.available() {
355 let to_add = count - self.available();
356 self.offsets.reserve(to_add);
357 self.data.reserve(to_add);
358 for _ in 0..to_add {
359 self.offsets.push(self.data.len());
360 self.data.push(T::default());
361 }
362 }
363 self.spawn_exact(count)
364 }
365}
366
367impl<'a, T> IntoIterator for &'a Pool<T> {
368 type Item = &'a T;
369 type IntoIter = Iter<'a, T>;
370
371 fn into_iter(self) -> Self::IntoIter {
372 self.iter()
373 }
374}
375
376impl<'a, T> IntoIterator for &'a mut Pool<T> {
377 type Item = &'a mut T;
378 type IntoIter = IterMut<'a, T>;
379
380 fn into_iter(self) -> Self::IntoIter {
381 self.iter_mut()
382 }
383}
384
385impl<T: fmt::Debug> fmt::Debug for Pool<T> {
386 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
387 let mut lst = f.debug_list();
388 for obj in self.iter() {
389 lst.entry(obj);
390 }
391 lst.finish()
392 }
393}
394
395impl<T: PartialEq> PartialEq for Pool<T> {
396 fn eq(&self, other: &Self) -> bool {
397 let are_alive_equal =
398 self.iter().zip(other.iter())
399 .all(| (s, o) | {
400 s == o
401 });
402 self.len() == other.len() && are_alive_equal
404 }
405}