1#![doc = include_str!("../README.md")]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![no_std]
4
5extern crate alloc;
6
7use alloc::vec::Vec;
8use core::{
9 fmt,
10 hash::{Hash, Hasher},
11 iter,
12 marker::PhantomData,
13 num::NonZero,
14 ops::{Index, IndexMut, Range},
15 slice,
16};
17
18mod util;
19
20pub trait Id: Copy + Ord {
25 const MAX: usize;
27
28 fn from_usize(idx: usize) -> Self;
36
37 fn into_usize(self) -> usize;
41}
42
43macro_rules! impl_id_for_nums {
44 ($($ty:ty),*) => {$(
45 impl Id for $ty {
46 const MAX: usize = <$ty>::MAX as usize;
47 #[inline]
48 fn from_usize(idx: usize) -> Self {
49 assert!(idx <= <Self as Id>::MAX);
50 idx as $ty
51 }
52 #[inline]
53 fn into_usize(self) -> usize {
54 self as usize
55 }
56 }
57 impl Id for NonZero<$ty> {
58 const MAX: usize = (<$ty>::MAX - 1) as usize;
59 #[inline]
60 fn from_usize(idx: usize) -> Self {
61 assert!(idx <= <Self as Id>::MAX);
62 unsafe { NonZero::new_unchecked((idx + 1) as $ty) }
63 }
64 #[inline]
65 fn into_usize(self) -> usize {
66 (self.get() - 1) as usize
67 }
68 }
69 )*};
70}
71impl_id_for_nums!(u8, u16, u32, u64, usize);
72
73pub struct Idx<T, I: Id> {
88 raw: I,
89 phantom: PhantomData<fn() -> T>,
90}
91
92impl<T, I: Id> Idx<T, I> {
93 #[inline]
107 pub const fn into_raw(self) -> I {
108 self.raw
109 }
110}
111
112impl<T, I: Id> Clone for Idx<T, I> {
113 #[inline]
114 fn clone(&self) -> Self {
115 *self
116 }
117}
118impl<T, I: Id> Copy for Idx<T, I> {}
119
120impl<T, I: Id + fmt::Debug> fmt::Debug for Idx<T, I> {
121 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
122 let t_name = util::simple_type_name::<T>();
123 let i_name = util::simple_type_name::<I>();
124 write!(fmt, "Idx::<{}, {}>({:?})", t_name, i_name, self.raw)
125 }
126}
127
128impl<T, I: Id> PartialEq for Idx<T, I> {
129 #[inline]
130 fn eq(&self, other: &Self) -> bool {
131 self.raw == other.raw
132 }
133}
134impl<T, I: Id> Eq for Idx<T, I> {}
135
136impl<T, I: Id> Ord for Idx<T, I> {
137 #[inline]
138 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
139 self.raw.cmp(&other.raw)
140 }
141}
142
143impl<T, I: Id> PartialOrd for Idx<T, I> {
144 #[inline]
145 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
146 Some(self.cmp(other))
147 }
148}
149
150impl<T, I: Id + Hash> Hash for Idx<T, I> {
151 #[inline]
152 fn hash<H: Hasher>(&self, state: &mut H) {
153 self.raw.hash(state)
154 }
155}
156
157pub struct IdxSpan<T, I: Id> {
173 start: I,
174 end: I,
175 phantom: PhantomData<fn() -> T>,
176}
177
178impl<T, I: Id> IdxSpan<T, I> {
179 #[inline]
181 pub const fn new(range: Range<I>) -> Self {
182 Self { start: range.start, end: range.end, phantom: PhantomData }
183 }
184
185 #[inline]
187 pub const fn start(&self) -> I {
188 self.start
189 }
190
191 #[inline]
193 pub const fn end(&self) -> I {
194 self.end
195 }
196
197 #[inline]
199 pub fn len(&self) -> usize {
200 self.end.into_usize() - self.start.into_usize()
201 }
202
203 #[inline]
205 pub fn is_empty(&self) -> bool {
206 self.start == self.end
207 }
208}
209
210impl<T, I: Id> Clone for IdxSpan<T, I> {
211 #[inline]
212 fn clone(&self) -> Self {
213 *self
214 }
215}
216impl<T, I: Id> Copy for IdxSpan<T, I> {}
217
218impl<T, I: Id + fmt::Debug> fmt::Debug for IdxSpan<T, I> {
219 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
220 let t_name = util::simple_type_name::<T>();
221 let i_name = util::simple_type_name::<I>();
222 write!(fmt, "IdxSpan::<{}, {}>({:?}..{:?})", t_name, i_name, self.start, self.end)
223 }
224}
225
226impl<T, I: Id> PartialEq for IdxSpan<T, I> {
227 #[inline]
228 fn eq(&self, other: &Self) -> bool {
229 self.start == other.start && self.end == other.end
230 }
231}
232impl<T, I: Id> Eq for IdxSpan<T, I> {}
233
234impl<T, I: Id + Hash> Hash for IdxSpan<T, I> {
235 #[inline]
236 fn hash<H: Hasher>(&self, state: &mut H) {
237 self.start.hash(state);
238 self.end.hash(state);
239 }
240}
241
242pub struct Arena<T, I: Id> {
249 data: Vec<T>,
250 phantom: PhantomData<(I, T)>,
251}
252
253impl<T, I: Id> Arena<T, I> {
254 #[inline]
264 pub const fn new() -> Self {
265 Self { data: Vec::new(), phantom: PhantomData }
266 }
267
268 #[inline]
279 pub fn with_capacity(capacity: usize) -> Self {
280 Self { data: Vec::with_capacity(capacity), phantom: PhantomData }
281 }
282
283 #[inline]
302 pub fn len(&self) -> usize {
303 self.data.len()
304 }
305
306 #[inline]
317 pub fn capacity(&self) -> usize {
318 self.data.capacity()
319 }
320
321 #[inline]
334 pub fn is_empty(&self) -> bool {
335 self.data.is_empty()
336 }
337
338 #[inline]
355 pub fn alloc(&mut self, value: T) -> Idx<T, I> {
356 self.try_alloc(value).expect("arena is full")
357 }
358
359 #[inline]
363 pub fn try_alloc(&mut self, value: T) -> Option<Idx<T, I>> {
364 if self.data.len() >= I::MAX {
365 None
366 } else {
367 let id = I::from_usize(self.data.len());
368 self.data.push(value);
369 Some(Idx { raw: id, phantom: PhantomData })
370 }
371 }
372
373 #[inline]
389 pub fn alloc_many(&mut self, values: impl IntoIterator<Item = T>) -> IdxSpan<T, I> {
390 self.try_alloc_many(values).expect("arena is full")
391 }
392
393 #[inline]
397 pub fn try_alloc_many(&mut self, values: impl IntoIterator<Item = T>) -> Option<IdxSpan<T, I>> {
398 let start = I::from_usize(self.data.len());
399 let mut len = self.data.len();
400 for value in values {
401 if len >= I::MAX {
402 return None;
403 }
404 self.data.push(value);
405 len += 1;
406 }
407 let end = I::from_usize(len);
408 Some(IdxSpan::new(start..end))
409 }
410
411 #[inline]
430 pub fn iter(&self) -> Iter<'_, T, I> {
431 Iter { iter: self.data.iter().enumerate(), phantom: PhantomData }
432 }
433
434 #[inline]
452 pub fn iter_mut(&mut self) -> IterMut<'_, T, I> {
453 IterMut { iter: self.data.iter_mut().enumerate(), phantom: PhantomData }
454 }
455
456 #[inline]
472 pub fn values(&self) -> Values<'_, T, I> {
473 Values { iter: self.data.iter(), phantom: PhantomData }
474 }
475
476 #[inline]
495 pub fn values_mut(&mut self) -> ValuesMut<'_, T, I> {
496 ValuesMut { iter: self.data.iter_mut(), phantom: PhantomData }
497 }
498
499 #[inline]
513 pub fn shrink_to_fit(&mut self) {
514 self.data.shrink_to_fit();
515 }
516}
517
518impl<T, I: Id> Default for Arena<T, I> {
519 #[inline]
520 fn default() -> Self {
521 Self::new()
522 }
523}
524
525impl<T, I: Id> Index<Idx<T, I>> for Arena<T, I> {
526 type Output = T;
527
528 #[inline]
529 fn index(&self, idx: Idx<T, I>) -> &Self::Output {
530 &self.data[idx.raw.into_usize()]
531 }
532}
533
534impl<T, I: Id> Index<IdxSpan<T, I>> for Arena<T, I> {
535 type Output = [T];
536
537 #[inline]
538 fn index(&self, span: IdxSpan<T, I>) -> &Self::Output {
539 &self.data[span.start.into_usize()..span.end.into_usize()]
540 }
541}
542
543impl<T, I: Id> IndexMut<Idx<T, I>> for Arena<T, I> {
544 #[inline]
545 fn index_mut(&mut self, index: Idx<T, I>) -> &mut Self::Output {
546 &mut self.data[index.raw.into_usize()]
547 }
548}
549
550impl<T, I: Id> IndexMut<IdxSpan<T, I>> for Arena<T, I> {
551 #[inline]
552 fn index_mut(&mut self, span: IdxSpan<T, I>) -> &mut Self::Output {
553 &mut self.data[span.start.into_usize()..span.end.into_usize()]
554 }
555}
556
557impl<T: Clone, I: Id> Clone for Arena<T, I> {
558 #[inline]
559 fn clone(&self) -> Self {
560 Self { data: self.data.clone(), phantom: PhantomData }
561 }
562}
563
564impl<T: fmt::Debug, I: Id> fmt::Debug for Arena<T, I> {
565 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
566 f.debug_struct("Arena").field("len", &self.len()).field("data", &self.data).finish()
567 }
568}
569
570impl<T: PartialEq, I: Id> PartialEq for Arena<T, I> {
571 #[inline]
572 fn eq(&self, other: &Self) -> bool {
573 self.data == other.data
574 }
575}
576
577impl<T: Eq, I: Id> Eq for Arena<T, I> {}
578
579impl<T: Hash, I: Id> Hash for Arena<T, I> {
580 #[inline]
581 fn hash<H: Hasher>(&self, state: &mut H) {
582 self.data.hash(state)
583 }
584}
585
586impl<'a, T, I: Id> IntoIterator for &'a Arena<T, I> {
587 type Item = (Idx<T, I>, &'a T);
588 type IntoIter = Iter<'a, T, I>;
589
590 #[inline]
591 fn into_iter(self) -> Self::IntoIter {
592 self.iter()
593 }
594}
595
596impl<T, I: Id> IntoIterator for Arena<T, I> {
597 type Item = (Idx<T, I>, T);
598 type IntoIter = IntoIter<T, I>;
599
600 #[inline]
601 fn into_iter(self) -> Self::IntoIter {
602 IntoIter { iter: self.data.into_iter().enumerate(), phantom: PhantomData }
603 }
604}
605
606macro_rules! iter_iterator_impls {
607 ($ty:ty, type Item = $item_ty:ty;) => {
608 impl<'a, T, I: Id> Iterator for $ty {
609 type Item = $item_ty;
610 #[inline]
611 fn next(&mut self) -> Option<Self::Item> {
612 let (id, value) = self.iter.next().map(|(i, v)| (I::from_usize(i), v))?;
613 Some((Idx { raw: id, phantom: PhantomData }, value))
614 }
615 #[inline]
616 fn size_hint(&self) -> (usize, Option<usize>) {
617 self.iter.size_hint()
618 }
619 #[inline]
620 fn count(self) -> usize {
621 self.iter.count()
622 }
623 #[inline]
624 fn last(self) -> Option<Self::Item> {
625 self.iter
626 .last()
627 .map(|(i, v)| (Idx { raw: I::from_usize(i), phantom: PhantomData }, v))
628 }
629 #[inline]
630 fn nth(&mut self, n: usize) -> Option<Self::Item> {
631 let (id, value) = self.iter.nth(n).map(|(i, v)| (I::from_usize(i), v))?;
632 Some((Idx { raw: id, phantom: PhantomData }, value))
633 }
634 }
635 impl<'a, T, I: Id> DoubleEndedIterator for $ty {
636 #[inline]
637 fn next_back(&mut self) -> Option<Self::Item> {
638 let (id, value) = self.iter.next_back().map(|(i, v)| (I::from_usize(i), v))?;
639 Some((Idx { raw: id, phantom: PhantomData }, value))
640 }
641 }
642 impl<'a, T, I: Id> ExactSizeIterator for $ty {
643 #[inline]
644 fn len(&self) -> usize {
645 self.iter.len()
646 }
647 }
648 impl<'a, T, I: Id> iter::FusedIterator for $ty {}
649 };
650}
651
652pub struct Iter<'a, T, I: Id> {
653 iter: iter::Enumerate<slice::Iter<'a, T>>,
654 phantom: PhantomData<I>,
655}
656
657iter_iterator_impls! {
658 Iter<'a, T, I>,
659 type Item = (Idx<T, I>, &'a T);
660}
661
662impl<T, I: Id> Clone for Iter<'_, T, I> {
663 #[inline]
664 fn clone(&self) -> Self {
665 Self { iter: self.iter.clone(), phantom: PhantomData }
666 }
667}
668
669pub struct IterMut<'a, T, I: Id> {
670 iter: iter::Enumerate<slice::IterMut<'a, T>>,
671 phantom: PhantomData<I>,
672}
673
674iter_iterator_impls! {
675 IterMut<'a, T, I>,
676 type Item = (Idx<T, I>, &'a mut T);
677}
678
679pub struct IntoIter<T, I: Id> {
680 iter: iter::Enumerate<alloc::vec::IntoIter<T>>,
681 phantom: PhantomData<I>,
682}
683
684iter_iterator_impls! {
685 IntoIter<T, I>,
686 type Item = (Idx<T, I>, T);
687}
688
689impl<T: Clone, I: Id> Clone for IntoIter<T, I> {
690 #[inline]
691 fn clone(&self) -> Self {
692 Self { iter: self.iter.clone(), phantom: PhantomData }
693 }
694}
695
696macro_rules! values_iterator_impls {
697 ($ty:ty, type Item = $item_ty:ty;) => {
698 impl<'a, T, I: Id> Iterator for $ty {
699 type Item = $item_ty;
700 #[inline]
701 fn next(&mut self) -> Option<Self::Item> {
702 self.iter.next()
703 }
704 #[inline]
705 fn size_hint(&self) -> (usize, Option<usize>) {
706 self.iter.size_hint()
707 }
708 #[inline]
709 fn count(self) -> usize {
710 self.iter.count()
711 }
712 #[inline]
713 fn last(self) -> Option<Self::Item> {
714 self.iter.last()
715 }
716 #[inline]
717 fn nth(&mut self, n: usize) -> Option<Self::Item> {
718 self.iter.nth(n)
719 }
720 }
721 impl<'a, T, I: Id> DoubleEndedIterator for $ty {
722 #[inline]
723 fn next_back(&mut self) -> Option<Self::Item> {
724 self.iter.next_back()
725 }
726 }
727 impl<'a, T, I: Id> ExactSizeIterator for $ty {
728 #[inline]
729 fn len(&self) -> usize {
730 self.iter.len()
731 }
732 }
733 impl<'a, T, I: Id> iter::FusedIterator for $ty {}
734 };
735}
736
737pub struct Values<'a, T, I: Id> {
738 iter: slice::Iter<'a, T>,
739 phantom: PhantomData<I>,
740}
741
742values_iterator_impls! {
743 Values<'a, T, I>,
744 type Item = &'a T;
745}
746
747impl<T, I: Id> Clone for Values<'_, T, I> {
748 #[inline]
749 fn clone(&self) -> Self {
750 Self { iter: self.iter.clone(), phantom: PhantomData }
751 }
752}
753
754pub struct ValuesMut<'a, T, I: Id> {
755 iter: slice::IterMut<'a, T>,
756 phantom: PhantomData<I>,
757}
758
759values_iterator_impls! {
760 ValuesMut<'a, T, I>,
761 type Item = &'a mut T;
762}