1mod group;
2mod list;
3mod storage;
4
5use core::{
6 alloc::{AllocError, Layout},
7 any::Any,
8 cell::{Cell, UnsafeCell},
9 fmt,
10 hash::Hash,
11 mem::MaybeUninit,
12 ops::{Deref, DerefMut},
13 ptr::NonNull,
14};
15
16pub use self::{
17 group::EntityGroup,
18 list::{EntityCursor, EntityCursorMut, EntityIter, EntityList, MaybeDefaultEntityIter},
19 storage::{EntityRange, EntityRangeMut, EntityStorage},
20};
21use crate::any::*;
22
23pub trait Entity: Any {}
25
26#[allow(unused_variables)]
33pub trait EntityListItem: Sized + Entity {
34 #[inline]
36 fn on_inserted(this: UnsafeIntrusiveEntityRef<Self>, cursor: &mut EntityCursorMut<'_, Self>) {}
37 #[inline]
39 fn on_removed(this: UnsafeIntrusiveEntityRef<Self>, list: &mut EntityCursorMut<'_, Self>) {}
40 #[inline]
42 fn on_transfer(
43 this: UnsafeIntrusiveEntityRef<Self>,
44 from: &mut EntityList<Self>,
45 to: &mut EntityList<Self>,
46 ) {
47 }
48}
49
50impl<T: Sized + Entity> EntityListItem for T {
51 default fn on_inserted(
52 _this: UnsafeIntrusiveEntityRef<Self>,
53 _list: &mut EntityCursorMut<'_, Self>,
54 ) {
55 }
56
57 default fn on_removed(
58 _this: UnsafeIntrusiveEntityRef<Self>,
59 _list: &mut EntityCursorMut<'_, Self>,
60 ) {
61 }
62
63 default fn on_transfer(
64 _this: UnsafeIntrusiveEntityRef<Self>,
65 _from: &mut EntityList<Self>,
66 _to: &mut EntityList<Self>,
67 ) {
68 }
69}
70
71pub trait EntityParent<Child: ?Sized>: Entity {
75 fn offset() -> usize;
78}
79
80pub trait EntityWithParent: Entity {
88 type Parent: EntityParent<Self>;
90}
91
92pub trait EntityWithId: Entity {
96 type Id: EntityId;
97
98 fn id(&self) -> Self::Id;
99}
100
101pub trait StorableEntity {
103 fn index(&self) -> usize;
105 unsafe fn set_index(&mut self, index: usize);
114 #[inline(always)]
116 fn unlink(&mut self) {}
117}
118
119pub trait EntityId: Copy + Clone + PartialEq + Eq + PartialOrd + Ord + Hash + fmt::Display {
121 fn as_usize(&self) -> usize;
122}
123
124#[non_exhaustive]
126pub struct AliasingViolationError {
127 #[cfg(debug_assertions)]
128 location: &'static core::panic::Location<'static>,
129 kind: AliasingViolationKind,
130}
131
132#[derive(Debug)]
133enum AliasingViolationKind {
134 Immutable,
136 Mutable,
138}
139
140impl fmt::Display for AliasingViolationKind {
141 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142 match self {
143 Self::Immutable => f.write_str("already mutably borrowed"),
144 Self::Mutable => f.write_str("already borrowed"),
145 }
146 }
147}
148
149impl fmt::Debug for AliasingViolationError {
150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151 let mut builder = f.debug_struct("AliasingViolationError");
152 builder.field("kind", &self.kind);
153 #[cfg(debug_assertions)]
154 builder.field("location", &self.location);
155 builder.finish()
156 }
157}
158impl fmt::Display for AliasingViolationError {
159 #[cfg(debug_assertions)]
160 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161 write!(
162 f,
163 "{} in file '{}' at line {} and column {}",
164 &self.kind,
165 self.location.file(),
166 self.location.line(),
167 self.location.column()
168 )
169 }
170
171 #[cfg(not(debug_assertions))]
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 write!(f, "{}", &self.kind)
174 }
175}
176
177pub type UnsafeEntityRef<T> = RawEntityRef<T, ()>;
179
180pub type UnsafeIntrusiveEntityRef<T> = RawEntityRef<T, IntrusiveLink>;
182
183pub struct IntrusiveLink {
184 link: intrusive_collections::LinkedListLink,
185 parent: Cell<*const ()>,
186}
187
188impl Default for IntrusiveLink {
189 fn default() -> Self {
190 Self {
191 link: Default::default(),
192 parent: Cell::new(core::ptr::null()),
193 }
194 }
195}
196
197impl IntrusiveLink {
198 #[inline]
199 pub fn is_linked(&self) -> bool {
200 self.link.is_linked()
201 }
202}
203
204impl IntrusiveLink {
205 pub(self) fn set_parent<T>(&self, parent: Option<UnsafeIntrusiveEntityRef<T>>) {
206 if let Some(parent) = parent {
207 assert!(
208 self.link.is_linked(),
209 "must add entity to parent entity list before setting parent"
210 );
211 self.parent.set(UnsafeIntrusiveEntityRef::as_ptr(&parent).cast());
212 } else if self.parent.get().is_null() {
213 panic!("no parent previously set");
214 } else {
215 self.parent.set(core::ptr::null());
216 }
217 }
218
219 pub fn parent<T>(&self) -> Option<UnsafeIntrusiveEntityRef<T>> {
220 let parent = self.parent.get();
221 if parent.is_null() {
222 None
224 } else {
225 Some(unsafe { UnsafeIntrusiveEntityRef::from_raw(parent.cast()) })
226 }
227 }
228}
229
230pub struct RawEntityRef<T: ?Sized, Metadata = ()> {
260 inner: NonNull<RawEntityMetadata<T, Metadata>>,
261}
262impl<T: ?Sized, Metadata> Copy for RawEntityRef<T, Metadata> {}
263impl<T: ?Sized, Metadata> Clone for RawEntityRef<T, Metadata> {
264 fn clone(&self) -> Self {
265 *self
266 }
267}
268impl<T: ?Sized, Metadata> RawEntityRef<T, Metadata> {
269 #[inline]
285 unsafe fn from_inner(inner: NonNull<RawEntityMetadata<T, Metadata>>) -> Self {
286 Self { inner }
287 }
288
289 #[inline]
290 unsafe fn from_ptr(ptr: *mut RawEntityMetadata<T, Metadata>) -> Self {
291 debug_assert!(!ptr.is_null());
292 Self::from_inner(NonNull::new_unchecked(ptr))
293 }
294
295 #[inline]
296 fn into_inner(this: Self) -> NonNull<RawEntityMetadata<T, Metadata>> {
297 this.inner
298 }
299}
300
301impl<T: 'static, Metadata: 'static> RawEntityRef<T, Metadata> {
302 pub fn new_with_metadata(value: T, metadata: Metadata, arena: &blink_alloc::Blink) -> Self {
310 unsafe {
311 Self::from_inner(NonNull::new_unchecked(
312 arena.put(RawEntityMetadata::new(value, metadata)),
313 ))
314 }
315 }
316
317 pub fn new_uninit_with_metadata(
326 metadata: Metadata,
327 arena: &blink_alloc::Blink,
328 ) -> RawEntityRef<MaybeUninit<T>, Metadata> {
329 unsafe {
330 RawEntityRef::from_ptr(RawEntityRef::allocate_for_layout(
331 metadata,
332 Layout::new::<T>(),
333 |layout| arena.allocator().allocate(layout).map_err(|_| AllocError),
334 <*mut u8>::cast,
335 ))
336 }
337 }
338}
339
340impl<T: 'static> RawEntityRef<T, ()> {
341 pub fn new(value: T, arena: &blink_alloc::Blink) -> Self {
342 RawEntityRef::new_with_metadata(value, (), arena)
343 }
344
345 pub fn new_uninit(arena: &blink_alloc::Blink) -> RawEntityRef<MaybeUninit<T>, ()> {
346 RawEntityRef::new_uninit_with_metadata((), arena)
347 }
348}
349
350impl<T, Metadata> RawEntityRef<MaybeUninit<T>, Metadata> {
351 #[inline]
359 pub unsafe fn assume_init(self) -> RawEntityRef<T, Metadata> {
360 let ptr = Self::into_inner(self);
361 unsafe { RawEntityRef::from_inner(ptr.cast()) }
362 }
363}
364
365impl<T: ?Sized, Metadata> RawEntityRef<T, Metadata> {
366 pub fn into_raw(this: Self) -> *const T {
383 Self::as_ptr(&this)
384 }
385
386 pub fn as_ptr(this: &Self) -> *const T {
387 let ptr: *mut RawEntityMetadata<T, Metadata> = NonNull::as_ptr(this.inner);
388
389 let ptr = unsafe { core::ptr::addr_of_mut!((*ptr).entity.cell) };
393 UnsafeCell::raw_get(ptr).cast_const()
394 }
395
396 pub unsafe fn from_raw(ptr: *const T) -> Self {
403 let offset = unsafe { RawEntityMetadata::<T, Metadata>::data_offset(ptr) };
404
405 let entity_ptr = unsafe { ptr.byte_sub(offset) as *mut RawEntityMetadata<T, Metadata> };
407
408 unsafe { Self::from_ptr(entity_ptr) }
409 }
410
411 #[track_caller]
413 pub fn borrow<'a, 'b: 'a>(&'a self) -> EntityRef<'b, T> {
414 let ptr: *mut RawEntityMetadata<T, Metadata> = NonNull::as_ptr(self.inner);
415 unsafe { (*core::ptr::addr_of!((*ptr).entity)).borrow() }
416 }
417
418 #[track_caller]
420 pub fn borrow_mut<'a, 'b: 'a>(&'a mut self) -> EntityMut<'b, T> {
421 let ptr: *mut RawEntityMetadata<T, Metadata> = NonNull::as_ptr(self.inner);
422 unsafe { (*core::ptr::addr_of!((*ptr).entity)).borrow_mut() }
423 }
424
425 pub fn try_borrow_mut<'a, 'b: 'a>(&'a mut self) -> Option<EntityMut<'b, T>> {
429 let ptr: *mut RawEntityMetadata<T, Metadata> = NonNull::as_ptr(self.inner);
430 unsafe { (*core::ptr::addr_of!((*ptr).entity)).try_borrow_mut().ok() }
431 }
432
433 pub fn ptr_eq(this: &Self, other: &Self) -> bool {
434 core::ptr::addr_eq(this.inner.as_ptr(), other.inner.as_ptr())
435 }
436
437 unsafe fn allocate_for_layout<F, F2>(
438 metadata: Metadata,
439 value_layout: Layout,
440 allocate: F,
441 mem_to_metadata: F2,
442 ) -> *mut RawEntityMetadata<T, Metadata>
443 where
444 F: FnOnce(Layout) -> Result<NonNull<[u8]>, AllocError>,
445 F2: FnOnce(*mut u8) -> *mut RawEntityMetadata<T, Metadata>,
446 {
447 use alloc::alloc::handle_alloc_error;
448
449 let layout = raw_entity_metadata_layout_for_value_layout::<Metadata>(value_layout);
450 unsafe {
451 RawEntityRef::try_allocate_for_layout(metadata, value_layout, allocate, mem_to_metadata)
452 .unwrap_or_else(|_| handle_alloc_error(layout))
453 }
454 }
455
456 #[inline]
457 unsafe fn try_allocate_for_layout<F, F2>(
458 metadata: Metadata,
459 value_layout: Layout,
460 allocate: F,
461 mem_to_metadata: F2,
462 ) -> Result<*mut RawEntityMetadata<T, Metadata>, AllocError>
463 where
464 F: FnOnce(Layout) -> Result<NonNull<[u8]>, AllocError>,
465 F2: FnOnce(*mut u8) -> *mut RawEntityMetadata<T, Metadata>,
466 {
467 let layout = raw_entity_metadata_layout_for_value_layout::<Metadata>(value_layout);
468 let ptr = allocate(layout)?;
469 let inner = mem_to_metadata(ptr.as_non_null_ptr().as_ptr());
470 unsafe {
471 debug_assert_eq!(Layout::for_value_raw(inner), layout);
472
473 core::ptr::addr_of_mut!((*inner).metadata).write(metadata);
474 core::ptr::addr_of_mut!((*inner).entity.borrow).write(Cell::new(BorrowFlag::UNUSED));
475 #[cfg(debug_assertions)]
476 core::ptr::addr_of_mut!((*inner).entity.borrowed_at).write(Cell::new(None));
477 }
478
479 Ok(inner)
480 }
481}
482
483impl<From: ?Sized, Metadata: 'static> RawEntityRef<From, Metadata> {
484 #[inline]
488 pub fn try_downcast<To>(
489 self,
490 ) -> Result<RawEntityRef<To, Metadata>, RawEntityRef<From, Metadata>>
491 where
492 To: DowncastFromRef<From> + 'static,
493 From: 'static,
494 {
495 RawEntityRef::<To, Metadata>::try_downcast_from(self)
496 }
497
498 #[inline]
502 pub fn try_downcast_ref<To, Obj>(&self) -> Option<RawEntityRef<To, Metadata>>
503 where
504 To: DowncastFromRef<From> + 'static,
505 From: Is<Obj> + AsAny + 'static,
506 Obj: ?Sized,
507 {
508 RawEntityRef::<To, Metadata>::try_downcast_from_ref(self)
509 }
510
511 #[inline]
515 #[track_caller]
516 pub fn downcast<To, Obj>(self) -> RawEntityRef<To, Metadata>
517 where
518 To: DowncastFromRef<From> + 'static,
519 From: Is<Obj> + AsAny + 'static,
520 Obj: ?Sized,
521 {
522 RawEntityRef::<To, Metadata>::downcast_from(self)
523 }
524
525 #[inline]
529 #[track_caller]
530 pub fn downcast_ref<To, Obj>(&self) -> RawEntityRef<To, Metadata>
531 where
532 To: DowncastFromRef<From> + 'static,
533 From: Is<Obj> + AsAny + 'static,
534 Obj: ?Sized,
535 {
536 RawEntityRef::<To, Metadata>::downcast_from_ref(self)
537 }
538}
539
540impl<To, Metadata: 'static> RawEntityRef<To, Metadata> {
541 pub fn try_downcast_from<From>(
542 from: RawEntityRef<From, Metadata>,
543 ) -> Result<Self, RawEntityRef<From, Metadata>>
544 where
545 From: ?Sized + 'static,
546 To: DowncastFromRef<From> + 'static,
547 {
548 let borrow = from.borrow();
549 <To as DowncastFromRef<From>>::downcast_from_ref(&*borrow)
550 .map(|to| unsafe { RawEntityRef::from_raw(to) })
551 .ok_or(from)
552 }
553
554 pub fn try_downcast_from_ref<From, Obj>(from: &RawEntityRef<From, Metadata>) -> Option<Self>
555 where
556 From: ?Sized + Is<Obj> + AsAny + 'static,
557 To: DowncastFromRef<From> + 'static,
558 Obj: ?Sized,
559 {
560 let borrow = from.borrow();
561 borrow.as_any().downcast_ref().map(|to| unsafe { RawEntityRef::from_raw(to) })
562 }
563
564 #[track_caller]
565 pub fn downcast_from<From, Obj>(from: RawEntityRef<From, Metadata>) -> Self
566 where
567 From: ?Sized + Is<Obj> + AsAny + 'static,
568 To: DowncastFromRef<From> + 'static,
569 Obj: ?Sized,
570 {
571 let borrow = from.borrow();
572 unsafe { RawEntityRef::from_raw(borrow.as_any().downcast_ref().expect("invalid cast")) }
573 }
574
575 #[track_caller]
576 pub fn downcast_from_ref<From, Obj>(from: &RawEntityRef<From, Metadata>) -> Self
577 where
578 From: ?Sized + Is<Obj> + AsAny + 'static,
579 To: DowncastFromRef<From> + 'static,
580 Obj: ?Sized,
581 {
582 let borrow = from.borrow();
583 unsafe { RawEntityRef::from_raw(borrow.as_any().downcast_ref().expect("invalid cast")) }
584 }
585}
586
587impl<From: ?Sized, Metadata: 'static> RawEntityRef<From, Metadata> {
588 #[inline]
592 pub fn upcast<To>(self) -> RawEntityRef<To, Metadata>
593 where
594 To: ?Sized,
595 From: core::marker::Unsize<To> + AsAny + 'static,
596 {
597 unsafe { RawEntityRef::<To, Metadata>::from_inner(self.inner) }
598 }
599}
600
601impl<T: crate::Op> RawEntityRef<T, IntrusiveLink> {
602 pub fn as_operation_ref(self) -> crate::OperationRef {
604 unsafe {
607 let ptr = Self::into_raw(self);
608 crate::OperationRef::from_raw(ptr.cast())
609 }
610 }
611}
612
613impl<T, U, Metadata> core::ops::CoerceUnsized<RawEntityRef<U, Metadata>>
614 for RawEntityRef<T, Metadata>
615where
616 T: ?Sized + core::marker::Unsize<U>,
617 U: ?Sized,
618{
619}
620impl<T: ?Sized, Metadata> Eq for RawEntityRef<T, Metadata> {}
621impl<T: ?Sized, Metadata> PartialEq for RawEntityRef<T, Metadata> {
622 #[inline]
623 fn eq(&self, other: &Self) -> bool {
624 Self::ptr_eq(self, other)
625 }
626}
627impl<T: ?Sized + EntityWithId, Metadata> PartialOrd for RawEntityRef<T, Metadata> {
628 #[inline]
629 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
630 Some(self.cmp(other))
631 }
632}
633impl<T: ?Sized + EntityWithId, Metadata> Ord for RawEntityRef<T, Metadata> {
634 #[inline]
635 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
636 self.borrow().id().cmp(&other.borrow().id())
637 }
638}
639impl<T: ?Sized, Metadata> core::hash::Hash for RawEntityRef<T, Metadata> {
640 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
641 self.inner.as_ptr().addr().hash(state);
642 }
643}
644impl<T: ?Sized, Metadata> fmt::Pointer for RawEntityRef<T, Metadata> {
645 #[inline]
646 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
647 fmt::Pointer::fmt(&Self::as_ptr(self), f)
648 }
649}
650impl<T: ?Sized + fmt::Display, Metadata> fmt::Display for RawEntityRef<T, Metadata> {
651 #[inline]
652 default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
653 write!(f, "{}", self.borrow())
654 }
655}
656impl<T: ?Sized + fmt::Display + EntityWithId, Metadata> fmt::Display for RawEntityRef<T, Metadata> {
657 #[inline]
658 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
659 write!(f, "{}", self.borrow().id())
660 }
661}
662
663impl<T: ?Sized + fmt::Debug, Metadata> fmt::Debug for RawEntityRef<T, Metadata> {
664 #[inline]
665 default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
666 fmt::Debug::fmt(&self.borrow(), f)
667 }
668}
669impl<T: ?Sized + fmt::Debug + EntityWithId, Metadata> fmt::Debug for RawEntityRef<T, Metadata> {
670 #[inline]
671 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
672 write!(f, "{}", self.borrow().id())
673 }
674}
675impl<T: ?Sized + crate::formatter::PrettyPrint, Metadata> crate::formatter::PrettyPrint
676 for RawEntityRef<T, Metadata>
677{
678 #[inline]
679 fn render(&self) -> crate::formatter::Document {
680 self.borrow().render()
681 }
682}
683impl<T: ?Sized + StorableEntity, Metadata> StorableEntity for RawEntityRef<T, Metadata> {
684 #[inline]
685 fn index(&self) -> usize {
686 self.borrow().index()
687 }
688
689 #[inline]
690 unsafe fn set_index(&mut self, index: usize) {
691 unsafe {
692 self.borrow_mut().set_index(index);
693 }
694 }
695
696 #[inline]
697 fn unlink(&mut self) {
698 self.borrow_mut().unlink()
699 }
700}
701impl<T: ?Sized + crate::Spanned, Metadata> crate::Spanned for RawEntityRef<T, Metadata> {
702 #[inline]
703 fn span(&self) -> crate::SourceSpan {
704 self.borrow().span()
705 }
706}
707
708pub struct EntityRef<'b, T: ?Sized + 'b> {
710 value: NonNull<T>,
711 borrow: BorrowRef<'b>,
712}
713impl<T: ?Sized> core::ops::Deref for EntityRef<'_, T> {
714 type Target = T;
715
716 fn deref(&self) -> &Self::Target {
717 unsafe { self.value.as_ref() }
719 }
720}
721impl<'b, T: ?Sized> EntityRef<'b, T> {
722 #[inline]
724 pub fn map<U: ?Sized, F>(orig: Self, f: F) -> EntityRef<'b, U>
725 where
726 F: FnOnce(&T) -> &U,
727 {
728 EntityRef {
729 value: NonNull::from(f(&*orig)),
730 borrow: orig.borrow,
731 }
732 }
733
734 pub fn project<'to, 'from: 'to, To, F>(
737 orig: EntityRef<'from, T>,
738 f: F,
739 ) -> EntityProjection<'from, To>
740 where
741 F: FnOnce(&'to T) -> To,
742 To: 'to,
743 {
744 EntityProjection {
745 value: f(unsafe { orig.value.as_ref() }),
746 borrow: orig.borrow,
747 }
748 }
749
750 pub fn into_entity_mut(self) -> Result<EntityMut<'b, T>, Self> {
752 let value = self.value;
753 match self.borrow.try_into_mut() {
754 Ok(borrow) => Ok(EntityMut {
755 value,
756 borrow,
757 _marker: core::marker::PhantomData,
758 }),
759 Err(borrow) => Err(Self { value, borrow }),
760 }
761 }
762
763 pub fn into_borrow_ref(self) -> BorrowRef<'b> {
764 self.borrow
765 }
766
767 pub fn from_raw_parts(value: NonNull<T>, borrow: BorrowRef<'b>) -> Self {
768 Self { value, borrow }
769 }
770}
771
772impl<'b, T, U> core::ops::CoerceUnsized<EntityRef<'b, U>> for EntityRef<'b, T>
773where
774 T: ?Sized + core::marker::Unsize<U>,
775 U: ?Sized,
776{
777}
778
779impl<T: ?Sized + fmt::Debug> fmt::Debug for EntityRef<'_, T> {
780 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
781 (**self).fmt(f)
782 }
783}
784impl<T: ?Sized + fmt::Display> fmt::Display for EntityRef<'_, T> {
785 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
786 (**self).fmt(f)
787 }
788}
789impl<T: ?Sized + crate::formatter::PrettyPrint> crate::formatter::PrettyPrint for EntityRef<'_, T> {
790 #[inline]
791 fn render(&self) -> crate::formatter::Document {
792 (**self).render()
793 }
794}
795impl<T: ?Sized + Eq> Eq for EntityRef<'_, T> {}
796impl<T: ?Sized + PartialEq> PartialEq for EntityRef<'_, T> {
797 fn eq(&self, other: &Self) -> bool {
798 **self == **other
799 }
800}
801impl<T: ?Sized + PartialOrd> PartialOrd for EntityRef<'_, T> {
802 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
803 (**self).partial_cmp(&**other)
804 }
805
806 fn ge(&self, other: &Self) -> bool {
807 **self >= **other
808 }
809
810 fn gt(&self, other: &Self) -> bool {
811 **self > **other
812 }
813
814 fn le(&self, other: &Self) -> bool {
815 **self <= **other
816 }
817
818 fn lt(&self, other: &Self) -> bool {
819 **self < **other
820 }
821}
822impl<T: ?Sized + Ord> Ord for EntityRef<'_, T> {
823 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
824 (**self).cmp(&**other)
825 }
826}
827impl<T: ?Sized + Hash> Hash for EntityRef<'_, T> {
828 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
829 (**self).hash(state);
830 }
831}
832
833pub struct EntityMut<'b, T: ?Sized> {
835 value: NonNull<T>,
840 #[allow(unused)]
843 borrow: BorrowRefMut<'b>,
844 _marker: core::marker::PhantomData<&'b mut T>,
846}
847impl<'b, T: ?Sized> EntityMut<'b, T> {
848 #[inline]
850 pub fn map<U: ?Sized, F>(mut orig: Self, f: F) -> EntityMut<'b, U>
851 where
852 F: FnOnce(&mut T) -> &mut U,
853 {
854 let value = NonNull::from(f(&mut *orig));
855 EntityMut {
856 value,
857 borrow: orig.borrow,
858 _marker: core::marker::PhantomData,
859 }
860 }
861
862 pub fn project<'to, 'from: 'to, To, F>(
865 mut orig: EntityMut<'from, T>,
866 f: F,
867 ) -> EntityProjectionMut<'from, To>
868 where
869 F: FnOnce(&'to mut T) -> To,
870 To: 'to,
871 {
872 EntityProjectionMut {
873 value: f(unsafe { orig.value.as_mut() }),
874 borrow: orig.borrow,
875 }
876 }
877
878 #[inline]
905 pub fn map_split<U: ?Sized, V: ?Sized, F>(
906 mut orig: Self,
907 f: F,
908 ) -> (EntityMut<'b, U>, EntityMut<'b, V>)
909 where
910 F: FnOnce(&mut T) -> (&mut U, &mut V),
911 {
912 let borrow = orig.borrow.clone();
913 let (a, b) = f(&mut *orig);
914 (
915 EntityMut {
916 value: NonNull::from(a),
917 borrow,
918 _marker: core::marker::PhantomData,
919 },
920 EntityMut {
921 value: NonNull::from(b),
922 borrow: orig.borrow,
923 _marker: core::marker::PhantomData,
924 },
925 )
926 }
927
928 pub fn into_entity_ref(self) -> EntityRef<'b, T> {
930 let value = self.value;
931 let borrow = self.into_borrow_ref_mut();
932
933 EntityRef {
934 value,
935 borrow: borrow.into_borrow_ref(),
936 }
937 }
938
939 #[doc(hidden)]
940 pub(crate) fn into_borrow_ref_mut(self) -> BorrowRefMut<'b> {
941 self.borrow
942 }
943
944 #[allow(unused)]
945 pub(crate) fn from_raw_parts(value: NonNull<T>, borrow: BorrowRefMut<'b>) -> Self {
946 Self {
947 value,
948 borrow,
949 _marker: core::marker::PhantomData,
950 }
951 }
952}
953impl<T: ?Sized> Deref for EntityMut<'_, T> {
954 type Target = T;
955
956 #[inline]
957 fn deref(&self) -> &T {
958 unsafe { self.value.as_ref() }
960 }
961}
962impl<T: ?Sized> DerefMut for EntityMut<'_, T> {
963 #[inline]
964 fn deref_mut(&mut self) -> &mut T {
965 unsafe { self.value.as_mut() }
967 }
968}
969
970impl<'b, T, U> core::ops::CoerceUnsized<EntityMut<'b, U>> for EntityMut<'b, T>
971where
972 T: ?Sized + core::marker::Unsize<U>,
973 U: ?Sized,
974{
975}
976
977impl<T: ?Sized + fmt::Debug> fmt::Debug for EntityMut<'_, T> {
978 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
979 (**self).fmt(f)
980 }
981}
982impl<T: ?Sized + fmt::Display> fmt::Display for EntityMut<'_, T> {
983 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
984 (**self).fmt(f)
985 }
986}
987impl<T: ?Sized + crate::formatter::PrettyPrint> crate::formatter::PrettyPrint for EntityMut<'_, T> {
988 #[inline]
989 fn render(&self) -> crate::formatter::Document {
990 (**self).render()
991 }
992}
993impl<T: ?Sized + Eq> Eq for EntityMut<'_, T> {}
994impl<T: ?Sized + PartialEq> PartialEq for EntityMut<'_, T> {
995 fn eq(&self, other: &Self) -> bool {
996 **self == **other
997 }
998}
999impl<T: ?Sized + PartialOrd> PartialOrd for EntityMut<'_, T> {
1000 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1001 (**self).partial_cmp(&**other)
1002 }
1003
1004 fn ge(&self, other: &Self) -> bool {
1005 **self >= **other
1006 }
1007
1008 fn gt(&self, other: &Self) -> bool {
1009 **self > **other
1010 }
1011
1012 fn le(&self, other: &Self) -> bool {
1013 **self <= **other
1014 }
1015
1016 fn lt(&self, other: &Self) -> bool {
1017 **self < **other
1018 }
1019}
1020impl<T: ?Sized + Ord> Ord for EntityMut<'_, T> {
1021 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1022 (**self).cmp(&**other)
1023 }
1024}
1025impl<T: ?Sized + Hash> Hash for EntityMut<'_, T> {
1026 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1027 (**self).hash(state);
1028 }
1029}
1030
1031pub struct EntityProjection<'b, T: 'b> {
1043 borrow: BorrowRef<'b>,
1044 value: T,
1045}
1046impl<T> core::ops::Deref for EntityProjection<'_, T> {
1047 type Target = T;
1048
1049 #[inline(always)]
1050 fn deref(&self) -> &Self::Target {
1051 &self.value
1052 }
1053}
1054impl<T> core::ops::DerefMut for EntityProjection<'_, T> {
1055 #[inline(always)]
1056 fn deref_mut(&mut self) -> &mut Self::Target {
1057 &mut self.value
1058 }
1059}
1060impl<'b, T> EntityProjection<'b, T> {
1061 pub fn map<U, F>(orig: Self, f: F) -> EntityProjection<'b, U>
1062 where
1063 F: FnOnce(T) -> U,
1064 {
1065 EntityProjection {
1066 value: f(orig.value),
1067 borrow: orig.borrow,
1068 }
1069 }
1070}
1071impl<T: fmt::Debug> fmt::Debug for EntityProjection<'_, T> {
1072 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1073 fmt::Debug::fmt(&self.value, f)
1074 }
1075}
1076impl<T: fmt::Display> fmt::Display for EntityProjection<'_, T> {
1077 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1078 fmt::Display::fmt(&self.value, f)
1079 }
1080}
1081impl<T: crate::formatter::PrettyPrint> crate::formatter::PrettyPrint for EntityProjection<'_, T> {
1082 #[inline]
1083 fn render(&self) -> crate::formatter::Document {
1084 crate::formatter::PrettyPrint::render(&self.value)
1085 }
1086}
1087impl<T: Eq> Eq for EntityProjection<'_, T> {}
1088impl<T: PartialEq> PartialEq for EntityProjection<'_, T> {
1089 fn eq(&self, other: &Self) -> bool {
1090 self.value == other.value
1091 }
1092}
1093impl<T: PartialOrd> PartialOrd for EntityProjection<'_, T> {
1094 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1095 self.value.partial_cmp(&other.value)
1096 }
1097
1098 fn ge(&self, other: &Self) -> bool {
1099 self.value.ge(&other.value)
1100 }
1101
1102 fn gt(&self, other: &Self) -> bool {
1103 self.value.gt(&other.value)
1104 }
1105
1106 fn le(&self, other: &Self) -> bool {
1107 self.value.le(&other.value)
1108 }
1109
1110 fn lt(&self, other: &Self) -> bool {
1111 self.value.lt(&other.value)
1112 }
1113}
1114impl<T: Ord> Ord for EntityProjection<'_, T> {
1115 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1116 self.value.cmp(&other.value)
1117 }
1118}
1119impl<T: Hash> Hash for EntityProjection<'_, T> {
1120 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1121 self.value.hash(state)
1122 }
1123}
1124
1125pub struct EntityProjectionMut<'b, T: 'b> {
1137 borrow: BorrowRefMut<'b>,
1138 value: T,
1139}
1140impl<T> core::ops::Deref for EntityProjectionMut<'_, T> {
1141 type Target = T;
1142
1143 #[inline(always)]
1144 fn deref(&self) -> &Self::Target {
1145 &self.value
1146 }
1147}
1148impl<T> core::ops::DerefMut for EntityProjectionMut<'_, T> {
1149 #[inline(always)]
1150 fn deref_mut(&mut self) -> &mut Self::Target {
1151 &mut self.value
1152 }
1153}
1154impl<'b, T> EntityProjectionMut<'b, T> {
1155 pub fn map<U, F>(orig: Self, f: F) -> EntityProjectionMut<'b, U>
1156 where
1157 F: FnOnce(T) -> U,
1158 {
1159 EntityProjectionMut {
1160 value: f(orig.value),
1161 borrow: orig.borrow,
1162 }
1163 }
1164}
1165impl<T: fmt::Debug> fmt::Debug for EntityProjectionMut<'_, T> {
1166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1167 fmt::Debug::fmt(&self.value, f)
1168 }
1169}
1170impl<T: fmt::Display> fmt::Display for EntityProjectionMut<'_, T> {
1171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1172 fmt::Display::fmt(&self.value, f)
1173 }
1174}
1175impl<T: crate::formatter::PrettyPrint> crate::formatter::PrettyPrint
1176 for EntityProjectionMut<'_, T>
1177{
1178 #[inline]
1179 fn render(&self) -> crate::formatter::Document {
1180 crate::formatter::PrettyPrint::render(&self.value)
1181 }
1182}
1183impl<T: Eq> Eq for EntityProjectionMut<'_, T> {}
1184impl<T: PartialEq> PartialEq for EntityProjectionMut<'_, T> {
1185 fn eq(&self, other: &Self) -> bool {
1186 self.value == other.value
1187 }
1188}
1189impl<T: PartialOrd> PartialOrd for EntityProjectionMut<'_, T> {
1190 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1191 self.value.partial_cmp(&other.value)
1192 }
1193
1194 fn ge(&self, other: &Self) -> bool {
1195 self.value.ge(&other.value)
1196 }
1197
1198 fn gt(&self, other: &Self) -> bool {
1199 self.value.gt(&other.value)
1200 }
1201
1202 fn le(&self, other: &Self) -> bool {
1203 self.value.le(&other.value)
1204 }
1205
1206 fn lt(&self, other: &Self) -> bool {
1207 self.value.lt(&other.value)
1208 }
1209}
1210impl<T: Ord> Ord for EntityProjectionMut<'_, T> {
1211 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1212 self.value.cmp(&other.value)
1213 }
1214}
1215impl<T: Hash> Hash for EntityProjectionMut<'_, T> {
1216 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1217 self.value.hash(state)
1218 }
1219}
1220
1221#[repr(C)]
1236#[doc(hidden)]
1237pub struct RawEntityMetadata<T: ?Sized, Metadata> {
1238 metadata: Metadata,
1239 entity: RawEntity<T>,
1240}
1241impl<T, Metadata> RawEntityMetadata<T, Metadata> {
1242 pub(crate) fn new(value: T, metadata: Metadata) -> Self {
1243 Self {
1244 metadata,
1245 entity: RawEntity::new(value),
1246 }
1247 }
1248}
1249impl<T: ?Sized, Metadata> RawEntityMetadata<T, Metadata> {
1250 #[track_caller]
1251 pub(crate) fn borrow(&self) -> EntityRef<'_, T> {
1252 let ptr = self as *const Self;
1253 unsafe { (*core::ptr::addr_of!((*ptr).entity)).borrow() }
1254 }
1255
1256 #[track_caller]
1257 pub(crate) fn borrow_mut(&self) -> EntityMut<'_, T> {
1258 let ptr = (self as *const Self).cast_mut();
1259 unsafe { (*core::ptr::addr_of_mut!((*ptr).entity)).borrow_mut() }
1260 }
1261
1262 #[inline]
1263 const fn metadata_offset() -> usize {
1264 core::mem::offset_of!(RawEntityMetadata<(), Metadata>, metadata)
1265 }
1266
1267 unsafe fn data_offset(ptr: *const T) -> usize {
1274 use core::mem::align_of_val_raw;
1275
1276 unsafe { RawEntityMetadata::<(), Metadata>::data_offset_align(align_of_val_raw(ptr)) }
1283 }
1284
1285 #[inline]
1286 fn data_offset_align(align: usize) -> usize {
1287 let layout = Layout::new::<RawEntityMetadata<(), Metadata>>();
1288 layout.size() + layout.padding_needed_for(align)
1289 }
1290}
1291
1292fn raw_entity_metadata_layout_for_value_layout<Metadata>(layout: Layout) -> Layout {
1293 Layout::new::<RawEntityMetadata<(), Metadata>>()
1294 .extend(layout)
1295 .unwrap()
1296 .0
1297 .pad_to_align()
1298}
1299
1300#[repr(C)]
1304pub struct RawEntity<T: ?Sized> {
1305 borrow: Cell<BorrowFlag>,
1306 #[cfg(debug_assertions)]
1307 borrowed_at: Cell<Option<&'static core::panic::Location<'static>>>,
1308 cell: UnsafeCell<T>,
1309}
1310
1311impl<T> RawEntity<T> {
1312 pub fn new(value: T) -> Self {
1313 Self {
1314 borrow: Cell::new(BorrowFlag::UNUSED),
1315 #[cfg(debug_assertions)]
1316 borrowed_at: Cell::new(None),
1317 cell: UnsafeCell::new(value),
1318 }
1319 }
1320
1321 #[allow(unused)]
1322 #[doc(hidden)]
1323 #[inline(always)]
1324 pub(crate) fn entity_addr(&self) -> *mut T {
1325 self.cell.get()
1326 }
1327
1328 #[allow(unused)]
1329 #[doc(hidden)]
1330 #[inline(always)]
1331 pub(crate) const fn entity_offset(&self) -> usize {
1332 core::mem::offset_of!(Self, cell)
1333 }
1334}
1335
1336impl<T, U> core::ops::CoerceUnsized<RawEntity<U>> for RawEntity<T> where
1337 T: core::ops::CoerceUnsized<U>
1338{
1339}
1340
1341impl<T: ?Sized> RawEntity<T> {
1342 #[track_caller]
1349 #[allow(unused)]
1350 pub unsafe fn borrow_unsafe(&self) -> (NonNull<T>, BorrowRef<'_>) {
1351 match self.try_borrow() {
1352 Ok(b) => (b.value, b.into_borrow_ref()),
1353 Err(err) => panic_aliasing_violation(err),
1354 }
1355 }
1356
1357 #[track_caller]
1364 pub unsafe fn borrow_mut_unsafe(&self) -> (NonNull<T>, BorrowRefMut<'_>) {
1365 match self.try_borrow_mut() {
1366 Ok(b) => (b.value, b.into_borrow_ref_mut()),
1367 Err(err) => panic_aliasing_violation(err),
1368 }
1369 }
1370
1371 #[track_caller]
1372 #[inline]
1373 pub fn borrow(&self) -> EntityRef<'_, T> {
1374 match self.try_borrow() {
1375 Ok(b) => b,
1376 Err(err) => panic_aliasing_violation(err),
1377 }
1378 }
1379
1380 #[inline]
1381 #[track_caller]
1382 pub fn try_borrow(&self) -> Result<EntityRef<'_, T>, AliasingViolationError> {
1383 match BorrowRef::new(&self.borrow) {
1384 Some(b) => {
1385 #[cfg(debug_assertions)]
1386 {
1387 if b.borrow.get() == BorrowFlag(1) {
1389 self.borrowed_at.set(Some(core::panic::Location::caller()));
1390 }
1391 }
1392
1393 let value = unsafe { NonNull::new_unchecked(self.cell.get()) };
1396 Ok(EntityRef { value, borrow: b })
1397 }
1398 None => Err(AliasingViolationError {
1399 #[cfg(debug_assertions)]
1400 location: self.borrowed_at.get().unwrap(),
1401 kind: AliasingViolationKind::Immutable,
1402 }),
1403 }
1404 }
1405
1406 #[inline]
1407 #[track_caller]
1408 pub fn borrow_mut(&self) -> EntityMut<'_, T> {
1409 match self.try_borrow_mut() {
1410 Ok(b) => b,
1411 Err(err) => panic_aliasing_violation(err),
1412 }
1413 }
1414
1415 #[inline]
1416 #[track_caller]
1417 pub fn try_borrow_mut(&self) -> Result<EntityMut<'_, T>, AliasingViolationError> {
1418 match BorrowRefMut::new(&self.borrow) {
1419 Some(b) => {
1420 #[cfg(debug_assertions)]
1421 {
1422 self.borrowed_at.set(Some(core::panic::Location::caller()));
1423 }
1424
1425 let value = unsafe { NonNull::new_unchecked(self.cell.get()) };
1427 Ok(EntityMut {
1428 value,
1429 borrow: b,
1430 _marker: core::marker::PhantomData,
1431 })
1432 }
1433 None => Err(AliasingViolationError {
1434 #[cfg(debug_assertions)]
1437 location: self.borrowed_at.get().unwrap(),
1438 kind: AliasingViolationKind::Mutable,
1439 }),
1440 }
1441 }
1442}
1443
1444#[doc(hidden)]
1445pub struct BorrowRef<'b> {
1446 borrow: &'b Cell<BorrowFlag>,
1447}
1448impl<'b> BorrowRef<'b> {
1449 #[inline]
1450 fn new(borrow: &'b Cell<BorrowFlag>) -> Option<Self> {
1451 let b = borrow.get().wrapping_add(1);
1452 if !b.is_reading() {
1453 None
1462 } else {
1463 borrow.set(b);
1468 Some(Self { borrow })
1469 }
1470 }
1471
1472 pub fn try_into_mut(self) -> Result<BorrowRefMut<'b>, Self> {
1474 use core::mem::ManuallyDrop;
1475
1476 let this = ManuallyDrop::new(self);
1478 let b = this.borrow.get();
1479 debug_assert!(b.is_reading());
1480 if (b - 1).is_unused() {
1481 this.borrow.set(BorrowFlag::UNUSED - 1);
1482 Ok(BorrowRefMut {
1483 borrow: this.borrow,
1484 })
1485 } else {
1486 Err(ManuallyDrop::into_inner(this))
1487 }
1488 }
1489}
1490impl Drop for BorrowRef<'_> {
1491 #[inline]
1492 fn drop(&mut self) {
1493 let borrow = self.borrow.get();
1494 debug_assert!(borrow.is_reading());
1495 self.borrow.set(borrow - 1);
1496 }
1497}
1498impl Clone for BorrowRef<'_> {
1499 #[inline]
1500 fn clone(&self) -> Self {
1501 let borrow = self.borrow.get();
1504 debug_assert!(borrow.is_reading());
1505 assert!(borrow != BorrowFlag::MAX);
1508 self.borrow.set(borrow + 1);
1509 BorrowRef {
1510 borrow: self.borrow,
1511 }
1512 }
1513}
1514
1515#[doc(hidden)]
1516pub struct BorrowRefMut<'b> {
1517 borrow: &'b Cell<BorrowFlag>,
1518}
1519impl Drop for BorrowRefMut<'_> {
1520 #[inline]
1521 fn drop(&mut self) {
1522 let borrow = self.borrow.get();
1523 debug_assert!(borrow.is_writing());
1524 self.borrow.set(borrow + 1);
1525 }
1526}
1527impl<'b> BorrowRefMut<'b> {
1528 pub fn into_borrow_ref(self) -> BorrowRef<'b> {
1530 let borrow = self.borrow;
1531 debug_assert!(borrow.get().is_writing());
1532 borrow.set(borrow.get() + 2);
1533 core::mem::forget(self);
1534 BorrowRef { borrow }
1535 }
1536
1537 #[inline]
1538 fn new(borrow: &'b Cell<BorrowFlag>) -> Option<Self> {
1539 match borrow.get() {
1544 BorrowFlag::UNUSED => {
1545 borrow.set(BorrowFlag::UNUSED - 1);
1546 Some(Self { borrow })
1547 }
1548 _ => None,
1549 }
1550 }
1551
1552 #[inline]
1558 fn clone(&self) -> Self {
1559 let borrow = self.borrow.get();
1560 debug_assert!(borrow.is_writing());
1561 assert!(borrow != BorrowFlag::MIN);
1563 self.borrow.set(borrow - 1);
1564 Self {
1565 borrow: self.borrow,
1566 }
1567 }
1568}
1569
1570#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
1574#[repr(transparent)]
1575struct BorrowFlag(isize);
1576impl BorrowFlag {
1577 const MAX: Self = Self(isize::MAX);
1578 const MIN: Self = Self(isize::MIN);
1579 const UNUSED: Self = Self(0);
1580
1581 #[allow(unused)]
1582 pub fn is_unused(&self) -> bool {
1583 self.0 == Self::UNUSED.0
1584 }
1585
1586 pub fn is_writing(&self) -> bool {
1587 self.0 < Self::UNUSED.0
1588 }
1589
1590 pub fn is_reading(&self) -> bool {
1591 self.0 > Self::UNUSED.0
1592 }
1593
1594 #[inline]
1595 pub const fn wrapping_add(self, rhs: isize) -> Self {
1596 Self(self.0.wrapping_add(rhs))
1597 }
1598}
1599impl core::ops::Add<isize> for BorrowFlag {
1600 type Output = BorrowFlag;
1601
1602 #[inline]
1603 fn add(self, rhs: isize) -> Self::Output {
1604 Self(self.0 + rhs)
1605 }
1606}
1607impl core::ops::Sub<isize> for BorrowFlag {
1608 type Output = BorrowFlag;
1609
1610 #[inline]
1611 fn sub(self, rhs: isize) -> Self::Output {
1612 Self(self.0 - rhs)
1613 }
1614}
1615
1616#[cfg_attr(not(panic = "abort"), inline(never))]
1618#[track_caller]
1619#[cold]
1620fn panic_aliasing_violation(err: AliasingViolationError) -> ! {
1621 panic!("{err:?}")
1622}