my_ecs/ds/
ptr.rs

1use super::types::TypeIdExt;
2use std::{
3    cmp, fmt, hash,
4    ops::{Deref, DerefMut},
5    ptr::NonNull,
6};
7
8/// A pointer that implements [`Send`] and [`Sync`] regardless of whether `T`
9/// implements both [`Send`] and [`Sync`].
10///
11/// # Safety
12///
13/// This pointer can be sent to another worker. Owner must guarantee that
14/// sending the pointer is safe. For instance, if you are controlling access to
15/// pointer over workers completely, it will be safe in terms of `Send` and
16/// `Sync`.
17#[derive(Debug)]
18#[repr(transparent)]
19pub struct SendSyncPtr<T: ?Sized>(NonNull<T>);
20
21unsafe impl<T: ?Sized> Send for SendSyncPtr<T> {}
22unsafe impl<T: ?Sized> Sync for SendSyncPtr<T> {}
23
24impl<T: ?Sized> SendSyncPtr<T> {
25    /// Creates a [`SendSyncPtr`] by wrapping the given pointer.
26    ///
27    /// # Examples
28    ///
29    /// ```
30    /// use my_ecs::ds::SendSyncPtr;
31    /// use std::ptr::NonNull;
32    ///
33    /// let mut v = 0;
34    /// let ptr = NonNull::new(&mut v as *mut i32).unwrap();
35    /// let ptr = SendSyncPtr::new(ptr);
36    /// ```
37    #[inline]
38    pub const fn new(ptr: NonNull<T>) -> Self {
39        Self(ptr)
40    }
41
42    /// Creates a [`SendSyncPtr`] that is dangling, but well-aligned.
43    ///
44    /// In many Rust functions, they require aligned pointers even if they are
45    /// some trash values. This function will be usuful in that cases.
46    ///
47    /// # Examples
48    ///
49    /// ```
50    /// use my_ecs::ds::SendSyncPtr;
51    /// use std::ptr::NonNull;
52    ///
53    /// let dangling = SendSyncPtr::<i32>::dangling();
54    /// ```
55    #[inline]
56    pub const fn dangling() -> Self
57    where
58        T: Sized,
59    {
60        Self::new(NonNull::dangling())
61    }
62
63    /// Returns true if the pointer is dangling.
64    ///
65    /// # Examples
66    ///
67    /// ```
68    /// use my_ecs::ds::SendSyncPtr;
69    ///
70    /// let dangling = SendSyncPtr::<i32>::dangling();
71    /// assert!(dangling.is_dangling());
72    /// ```
73    #[inline]
74    pub fn is_dangling(&self) -> bool
75    where
76        T: Sized,
77    {
78        self == &Self::dangling()
79    }
80
81    /// Creates a [`NonNull`] from this pointer.
82    ///
83    /// # Examples
84    ///
85    /// ```
86    /// use my_ecs::ds::SendSyncPtr;
87    /// use std::ptr::NonNull;
88    ///
89    /// let mut v = 0;
90    /// let nn = NonNull::new(&mut v as *mut i32).unwrap();
91    /// let ptr = SendSyncPtr::new(nn);
92    /// assert_eq!(ptr.as_nonnull(), nn);
93    /// ```
94    #[inline]
95    pub const fn as_nonnull(self) -> NonNull<T> {
96        self.0
97    }
98
99    /// Creates a raw pointer from this pointer.
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// use my_ecs::ds::SendSyncPtr;
105    /// use std::ptr::NonNull;
106    ///
107    /// let mut v = 0;
108    /// let nn = NonNull::new(&mut v as *mut i32).unwrap();
109    /// let ptr = SendSyncPtr::new(nn);
110    /// assert_eq!(ptr.as_ptr(), nn.as_ptr());
111    /// ```
112    #[inline]
113    pub const fn as_ptr(self) -> *mut T {
114        self.0.as_ptr()
115    }
116
117    /// Returns a shared reference to the value.
118    ///
119    /// # Safety
120    ///
121    /// See [`NonNull::as_ref`].
122    ///
123    /// # Examples
124    ///
125    /// ```
126    /// use my_ecs::ds::SendSyncPtr;
127    /// use std::ptr::NonNull;
128    ///
129    /// let mut v = 0;
130    /// let ptr = NonNull::new(&mut v as *mut i32).unwrap();
131    /// let ptr = SendSyncPtr::new(ptr);
132    /// let ref_v = unsafe { ptr.as_ref() };
133    /// assert_eq!(ref_v, &v);
134    /// ```
135    #[inline]
136    pub const unsafe fn as_ref<'a>(&self) -> &'a T {
137        unsafe { self.0.as_ref() }
138    }
139
140    /// Returns a mutable reference to the value.
141    ///
142    /// # Safety
143    ///
144    /// See [`NonNull::as_mut`].
145    ///
146    /// # Examples
147    ///
148    /// ```
149    /// use my_ecs::ds::SendSyncPtr;
150    /// use std::ptr::NonNull;
151    ///
152    /// let mut v = 0;
153    /// let ptr = NonNull::new(&mut v as *mut i32).unwrap();
154    /// let mut ptr = SendSyncPtr::new(ptr);
155    /// let mut_v = unsafe { ptr.as_mut() };
156    /// assert_eq!(mut_v, &mut v);
157    /// ```
158    #[inline]
159    pub unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
160        unsafe { self.0.as_mut() }
161    }
162
163    /// Adds an offset to the pointer then returns the result.
164    ///
165    /// Note that `count` is in units of `T`. For example, `count` = 3 means
166    /// 12 bytes offset if `T` is `i32`.
167    ///
168    /// # Safety
169    ///
170    /// See [`NonNull::add`].
171    ///
172    /// # Examples
173    ///
174    /// ```
175    /// use my_ecs::ds::SendSyncPtr;
176    /// use std::ptr::NonNull;
177    ///
178    /// let arr: [char; 3] = ['a', 'b', 'c'];
179    /// let ptr = NonNull::new(arr.as_ptr().cast_mut()).unwrap();
180    /// let ptr = SendSyncPtr::new(ptr);
181    ///
182    /// let ref_v = unsafe { ptr.add(1).as_ref() };
183    /// assert_eq!(ref_v, &'b');
184    ///
185    /// let ref_v = unsafe { ptr.add(2).as_ref() };
186    /// assert_eq!(ref_v, &'c');
187    /// ```
188    #[inline]
189    pub const unsafe fn add(self, count: usize) -> Self
190    where
191        T: Sized,
192    {
193        let inner = unsafe { self.0.add(count) };
194        Self::new(inner)
195    }
196
197    /// Subtracts an offset from the pointer then returns the result.
198    ///
199    /// Note that `count` is in units of `T`. For example, `count` = 3 means
200    /// 12 bytes offset if `T` is `i32`.
201    ///
202    /// # Safety
203    ///
204    /// See [`NonNull::sub`].
205    ///
206    /// # Examples
207    ///
208    /// ```
209    /// use my_ecs::ds::SendSyncPtr;
210    /// use std::ptr::NonNull;
211    ///
212    /// let arr: [char; 3] = ['a', 'b', 'c'];
213    /// let ptr = NonNull::new((&arr[2] as *const char).cast_mut()).unwrap();
214    /// let ptr = SendSyncPtr::new(ptr);
215    ///
216    /// let ref_v = unsafe { ptr.sub(1).as_ref() };
217    /// assert_eq!(ref_v, &'b');
218    ///
219    /// let ref_v = unsafe { ptr.sub(2).as_ref() };
220    /// assert_eq!(ref_v, &'a');
221    /// ```
222    #[inline]
223    pub const unsafe fn sub(self, count: usize) -> Self
224    where
225        T: Sized,
226    {
227        let inner = unsafe { self.0.sub(count) };
228        Self::new(inner)
229    }
230
231    /// Casts the pointer to another type.
232    ///
233    /// # Examples
234    ///
235    /// ```
236    /// use my_ecs::ds::SendSyncPtr;
237    /// use std::ptr::NonNull;
238    ///
239    /// let mut v = 0x1234_5678;
240    /// let ptr = NonNull::new(&mut v as *mut i32).unwrap();
241    /// let ptr = SendSyncPtr::new(ptr);
242    ///
243    /// let ptr = ptr.cast::<[u8; 4]>();
244    /// let ref_v = unsafe { ptr.as_ref() };
245    /// assert_eq!(*ref_v, i32::to_ne_bytes(v));
246    /// ```
247    #[inline]
248    pub const fn cast<U>(self) -> SendSyncPtr<U> {
249        // Safety: Nothing has changed except `T` -> `U`.
250        SendSyncPtr::new(self.0.cast())
251    }
252}
253
254impl<T: ?Sized> PartialEq for SendSyncPtr<T> {
255    #[allow(ambiguous_wide_pointer_comparisons)]
256    #[inline]
257    fn eq(&self, other: &Self) -> bool {
258        self.as_ptr() == other.as_ptr()
259    }
260}
261
262impl<T: ?Sized> Eq for SendSyncPtr<T> {}
263
264impl<T: ?Sized> PartialOrd for SendSyncPtr<T> {
265    #[inline]
266    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
267        Some(self.cmp(other))
268    }
269}
270
271impl<T: ?Sized> Ord for SendSyncPtr<T> {
272    #[allow(ambiguous_wide_pointer_comparisons)]
273    #[inline]
274    fn cmp(&self, other: &Self) -> cmp::Ordering {
275        self.as_ptr().cmp(&other.as_ptr())
276    }
277}
278
279impl<T: ?Sized> hash::Hash for SendSyncPtr<T> {
280    #[inline]
281    fn hash<H: hash::Hasher>(&self, state: &mut H) {
282        self.0.hash(state)
283    }
284}
285
286impl<T: ?Sized> Clone for SendSyncPtr<T> {
287    #[inline]
288    fn clone(&self) -> Self {
289        *self
290    }
291}
292
293impl<T: ?Sized> Copy for SendSyncPtr<T> {}
294
295/// A pointer that is extended with type id or name.
296///
297/// If 'check' feature is enabled, it contains type id or name. Otherwise, it's
298/// just a [`NonNull`]. This is useful when you want to know the type of the
299/// pointer.
300#[cfg_attr(not(feature = "check"), repr(transparent))]
301pub struct NonNullExt<T: ?Sized> {
302    inner: NonNull<T>,
303    #[cfg(feature = "check")]
304    ty_or_name: crate::util::Or<TypeIdExt, &'static str>,
305}
306
307impl<T: ?Sized> fmt::Debug for NonNullExt<T> {
308    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309        #[cfg(not(feature = "check"))]
310        {
311            self.inner.fmt(f)
312        }
313
314        #[cfg(feature = "check")]
315        {
316            write!(f, "NonNullExt({:?})", self.ty_or_name)
317        }
318    }
319}
320
321impl<T: ?Sized> NonNullExt<T> {
322    /// Creates a [`NonNullExt`] from the given pointer.
323    ///
324    /// Returns `None` if the pointer is null.
325    ///
326    /// # Examples
327    ///
328    /// ```
329    /// use my_ecs::ds::NonNullExt;
330    ///
331    /// let mut v = 0;
332    /// let ptr = NonNullExt::new(&mut v as *mut i32).unwrap();
333    /// ```
334    #[inline]
335    pub fn new(ptr: *mut T) -> Option<Self> {
336        let ptr = NonNull::new(ptr)?;
337        Some(Self::from_nonnull(ptr))
338    }
339
340    /// Creates a [`NonNullExt`] from the given pointer.
341    ///
342    /// # Safety
343    ///
344    /// The pointer must be non-null.
345    ///
346    /// # Examples
347    ///
348    /// ```
349    /// use my_ecs::ds::NonNullExt;
350    ///
351    /// let mut v = 0;
352    /// let ptr = unsafe { NonNullExt::new_unchecked(&mut v as *mut i32) };
353    /// ```
354    #[inline]
355    pub unsafe fn new_unchecked(ptr: *mut T) -> Self {
356        debug_assert!(
357            !ptr.is_null(),
358            "NonNullExt::new_unchecked: expected non-null pointer"
359        );
360
361        Self {
362            inner: unsafe { NonNull::new_unchecked(ptr) },
363            #[cfg(feature = "check")]
364            ty_or_name: crate::util::Or::B(std::any::type_name::<T>()),
365        }
366    }
367
368    /// Creates a [`NonNullExt`] from the given pointer.
369    ///
370    /// # Examples
371    ///
372    /// ```
373    /// use my_ecs::ds::NonNullExt;
374    /// use std::ptr::NonNull;
375    ///
376    /// let mut v = 0;
377    /// let ptr = NonNull::new(&mut v as *mut i32).unwrap();
378    /// let ptr = NonNullExt::from_nonnull(ptr);
379    /// ```
380    #[inline]
381    pub fn from_nonnull(ptr: NonNull<T>) -> Self {
382        Self {
383            inner: ptr,
384            #[cfg(feature = "check")]
385            ty_or_name: crate::util::Or::B(std::any::type_name::<T>()),
386        }
387    }
388
389    /// Creates a [`NonNullExt`] that is dangling, but well-aligned.
390    ///
391    /// In many Rust functions, they require aligned pointers even if they are
392    /// some trash values. This function will be usuful in that cases.
393    ///
394    /// # Examples
395    ///
396    /// ```
397    /// use my_ecs::ds::NonNullExt;
398    ///
399    /// let dangling = NonNullExt::<i32>::dangling();
400    /// ```
401    #[inline]
402    pub const fn dangling() -> Self
403    where
404        T: Sized,
405    {
406        Self {
407            inner: NonNull::dangling(),
408            #[cfg(feature = "check")]
409            ty_or_name: crate::util::Or::B(""), // type_name() is not const yet.
410        }
411    }
412
413    /// Returns true if the pointer is dangling.
414    ///
415    /// # Examples
416    ///
417    /// ```
418    /// use my_ecs::ds::NonNullExt;
419    ///
420    /// let dangling = NonNullExt::<i32>::dangling();
421    /// assert!(dangling.is_dangling());
422    /// ```
423    #[inline]
424    pub fn is_dangling(&self) -> bool
425    where
426        T: Sized,
427    {
428        self == &Self::dangling()
429    }
430
431    /// Sets the [`TypeIdExt`] to the pointer then returns the pointer.
432    ///
433    /// Basically, [`NonNullExt`] contains type name of the pointer if `check`
434    /// feature is enabled. You can replace it with the given `TypeIdExt`
435    /// using this method. But `check` feature is disabled, this method is
436    /// no-op.
437    ///
438    /// # Examples
439    ///
440    /// ```
441    /// use my_ecs::{prelude::*, ds::NonNullExt};
442    ///
443    /// let mut v = 0;
444    /// let ptr = NonNullExt::new(&mut v as *mut i32)
445    ///     .unwrap()
446    ///     .with_type(TypeIdExt::of::<i32>());
447    /// ```
448    #[inline]
449    pub fn with_type(self, _ty: TypeIdExt) -> Self {
450        #[cfg(not(feature = "check"))]
451        {
452            self
453        }
454
455        #[cfg(feature = "check")]
456        {
457            let mut this = self;
458            this.ty_or_name = crate::util::Or::A(_ty);
459            this
460        }
461    }
462
463    /// Returns [`TypeIdExt`] of the pointer if `check` feature is enabled and
464    /// the pointer contains `TypeIdExt` rather than type name.
465    ///
466    /// If you want to set the `TypeIdExt` to the pointer, call
467    /// [`NonNullExt::with_type`].
468    ///
469    /// # Examples
470    ///
471    /// ```
472    /// use my_ecs::{prelude::*, ds::NonNullExt};
473    ///
474    /// let mut v = 0;
475    /// let ptr = NonNullExt::new(&mut v as *mut i32)
476    ///     .unwrap()
477    ///     .with_type(TypeIdExt::of::<i32>());
478    /// ```
479    #[inline]
480    pub fn get_type(&self) -> Option<&TypeIdExt> {
481        #[cfg(not(feature = "check"))]
482        {
483            None
484        }
485
486        #[cfg(feature = "check")]
487        {
488            match &self.ty_or_name {
489                crate::util::Or::A(ty) => Some(ty),
490                crate::util::Or::B(_name) => None,
491            }
492        }
493    }
494
495    /// Returns type name of the pointer if `check` feature is enabled.
496    ///
497    /// # Examples
498    ///
499    /// ```
500    /// use my_ecs::ds::NonNullExt;
501    ///
502    /// let mut v = 0;
503    /// let ptr = NonNullExt::new(&mut v as *mut i32).unwrap();
504    /// let name = ptr.get_name();
505    /// ```
506    #[inline]
507    pub fn get_name(&self) -> Option<&'static str> {
508        #[cfg(not(feature = "check"))]
509        {
510            None
511        }
512
513        #[cfg(feature = "check")]
514        {
515            match &self.ty_or_name {
516                crate::util::Or::A(ty) => Some(ty.name()),
517                crate::util::Or::B(name) => Some(name),
518            }
519        }
520    }
521
522    /// Casts the pointer to another type.
523    ///
524    /// Note that this method resets [`TypeIdExt`] you set through
525    /// [`NonNullExt::with_type`].
526    ///
527    /// # Examples
528    ///
529    /// ```
530    /// use my_ecs::ds::NonNullExt;
531    ///
532    /// let mut v = 0x1234_5678;
533    /// let ptr = NonNullExt::new(&mut v as *mut i32).unwrap();
534    ///
535    /// let ptr = ptr.cast::<[u8; 4]>();
536    /// let ref_v = unsafe { ptr.as_ref() };
537    /// assert_eq!(*ref_v, i32::to_ne_bytes(v));
538    /// ```
539    #[inline]
540    pub fn cast<U>(self) -> NonNullExt<U> {
541        NonNullExt {
542            inner: self.inner.cast(),
543            #[cfg(feature = "check")]
544            ty_or_name: crate::util::Or::B(std::any::type_name::<U>()),
545        }
546    }
547
548    /// Adds an offset to the pointer then returns the result.
549    ///
550    /// Note that `count` is in units of `T`. For example, `count` = 3 means
551    /// 12 bytes offset if `T` is `i32`.
552    ///
553    /// # Safety
554    ///
555    /// See [`NonNull::add`].
556    ///
557    /// # Examples
558    ///
559    /// ```
560    /// use my_ecs::ds::NonNullExt;
561    ///
562    /// let arr: [char; 3] = ['a', 'b', 'c'];
563    /// let ptr = NonNullExt::new(arr.as_ptr().cast_mut()).unwrap();
564    ///
565    /// let ref_v = unsafe { ptr.add(1).as_ref() };
566    /// assert_eq!(ref_v, &'b');
567    ///
568    /// let ref_v = unsafe { ptr.add(2).as_ref() };
569    /// assert_eq!(ref_v, &'c');
570    /// ```
571    #[inline]
572    pub unsafe fn add(self, count: usize) -> Self
573    where
574        T: Sized,
575    {
576        let inner = unsafe { self.inner.add(count) };
577
578        Self {
579            inner,
580            #[cfg(feature = "check")]
581            ty_or_name: self.ty_or_name,
582        }
583    }
584
585    /// Subtracts an offset from the pointer then returns the result.
586    ///
587    /// Note that `count` is in units of `T`. For example, `count` = 3 means
588    /// 12 bytes offset if `T` is `i32`.
589    ///
590    /// # Safety
591    ///
592    /// See [`NonNull::sub`].
593    ///
594    /// # Examples
595    ///
596    /// ```
597    /// use my_ecs::ds::NonNullExt;
598    ///
599    /// let arr: [char; 3] = ['a', 'b', 'c'];
600    /// let ptr = NonNullExt::new((&arr[2] as *const char).cast_mut()).unwrap();
601    ///
602    /// let ref_v = unsafe { ptr.sub(1).as_ref() };
603    /// assert_eq!(ref_v, &'b');
604    ///
605    /// let ref_v = unsafe { ptr.sub(2).as_ref() };
606    /// assert_eq!(ref_v, &'a');
607    /// ```
608    #[inline]
609    pub unsafe fn sub(self, count: usize) -> Self
610    where
611        T: Sized,
612    {
613        let inner = unsafe { self.inner.sub(count) };
614
615        Self {
616            inner,
617            #[cfg(feature = "check")]
618            ty_or_name: self.ty_or_name,
619        }
620    }
621}
622
623impl<T: ?Sized> Deref for NonNullExt<T> {
624    type Target = NonNull<T>;
625
626    #[inline]
627    fn deref(&self) -> &Self::Target {
628        &self.inner
629    }
630}
631
632impl<T: ?Sized> DerefMut for NonNullExt<T> {
633    #[inline]
634    fn deref_mut(&mut self) -> &mut Self::Target {
635        &mut self.inner
636    }
637}
638
639impl<T: ?Sized> PartialEq for NonNullExt<T> {
640    #[allow(ambiguous_wide_pointer_comparisons)]
641    #[inline]
642    fn eq(&self, other: &Self) -> bool {
643        self.as_ptr() == other.as_ptr()
644    }
645}
646
647impl<T: ?Sized> Eq for NonNullExt<T> {}
648
649impl<T: ?Sized> PartialOrd for NonNullExt<T> {
650    #[inline]
651    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
652        Some(self.cmp(other))
653    }
654}
655
656impl<T: ?Sized> Ord for NonNullExt<T> {
657    #[allow(ambiguous_wide_pointer_comparisons)]
658    #[inline]
659    fn cmp(&self, other: &Self) -> cmp::Ordering {
660        self.as_ptr().cmp(&other.as_ptr())
661    }
662}
663
664impl<T: ?Sized> hash::Hash for NonNullExt<T> {
665    #[inline]
666    fn hash<H: hash::Hasher>(&self, state: &mut H) {
667        self.inner.hash(state)
668    }
669}
670
671impl<T: ?Sized> Clone for NonNullExt<T> {
672    #[inline]
673    fn clone(&self) -> Self {
674        *self
675    }
676}
677
678impl<T: ?Sized> Copy for NonNullExt<T> {}
679
680/// A wrapper of [`NonNullExt`] that can be used to manage a constant pointer.
681///
682/// When the `check` feature is enabled, the crate tracks whether
683/// [`ManagedMutPtr`] that has the same address is being created while the
684/// pointer is alive. This could be useful when you need extra debugging
685/// facility than `NonNullExt`.
686///
687/// # Safety
688///
689/// The pointer is used as a shared reference without unsafe function such as
690/// [`NonNull::as_ref`] because the pointer is completely managed. Therefore,
691/// You must make sure that the pointer will not violate any conditions of
692/// `Pointer to reference conversion` in [`std::ptr`] document.
693pub struct ManagedConstPtr<T: ?Sized> {
694    inner: NonNullExt<T>,
695    #[cfg(feature = "check")]
696    is_trace: bool,
697}
698
699impl<T: ?Sized> fmt::Debug for ManagedConstPtr<T> {
700    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
701        self.inner.fmt(f)
702    }
703}
704
705unsafe impl<T: ?Sized + Send> Send for ManagedConstPtr<T> {}
706
707impl<T: ?Sized> ManagedConstPtr<T> {
708    /// Creates a [`ManagedConstPtr`] from the given pointer.
709    ///
710    /// # Safety
711    ///
712    /// See [`ManagedConstPtr`] safety section.
713    ///
714    /// # Examples
715    ///
716    /// ```
717    /// use my_ecs::ds::{NonNullExt, ManagedConstPtr};
718    ///
719    /// let mut v = 0;
720    /// let ptr = NonNullExt::new(&mut v as *mut i32).unwrap();
721    /// let ptr = unsafe { ManagedConstPtr::new(ptr) };
722    /// ```
723    #[inline]
724    pub unsafe fn new(ptr: NonNullExt<T>) -> Self {
725        // Tracks the address because `is_trace` is true.
726        #[cfg(feature = "check")]
727        {
728            debug::insert_const_ptr(ptr);
729        }
730
731        Self {
732            inner: ptr,
733            #[cfg(feature = "check")]
734            is_trace: true,
735        }
736    }
737
738    /// Creates a [`ManagedConstPtr`] that is dangling, but well-aligned.
739    ///
740    /// In many Rust functions, they require aligned pointers even if they are
741    /// some trash values. This function will be usuful in that cases.
742    ///
743    /// # Examples
744    ///
745    /// ```
746    /// use my_ecs::ds::ManagedConstPtr;
747    ///
748    /// let dangling = ManagedConstPtr::<i32>::dangling();
749    /// ```
750    #[inline]
751    pub const fn dangling() -> Self
752    where
753        T: Sized,
754    {
755        Self {
756            inner: NonNullExt::dangling(),
757            #[cfg(feature = "check")]
758            is_trace: false,
759        }
760    }
761
762    /// Returns true if the pointer is dangling.
763    ///
764    /// # Examples
765    ///
766    /// ```
767    /// use my_ecs::ds::ManagedConstPtr;
768    ///
769    /// let dangling = ManagedConstPtr::<i32>::dangling();
770    /// assert!(dangling.is_dangling());
771    /// ```
772    #[inline]
773    pub fn is_dangling(&self) -> bool
774    where
775        T: Sized,
776    {
777        self == &Self::dangling()
778    }
779
780    /// Creates a [`NonNullExt`] from this pointer.
781    ///
782    /// # Examples
783    ///
784    /// ```
785    /// use my_ecs::ds::{NonNullExt, ManagedConstPtr};
786    ///
787    /// let mut v = 0;
788    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
789    /// let ptr = unsafe { ManagedConstPtr::new(nne) };
790    /// assert_eq!(ptr.as_nonnullext(), nne);
791    /// ```
792    #[inline]
793    pub fn as_nonnullext(&self) -> NonNullExt<T> {
794        self.inner
795    }
796
797    /// Creates a [`NonNull`] from this pointer.
798    ///
799    /// # Examples
800    ///
801    /// ```
802    /// use my_ecs::ds::{NonNullExt, ManagedConstPtr};
803    ///
804    /// let mut v = 0;
805    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
806    /// let ptr = unsafe { ManagedConstPtr::new(nne) };
807    /// assert_eq!(ptr.as_nonnull(), *nne);
808    /// ```
809    #[inline]
810    pub fn as_nonnull(&self) -> NonNull<T> {
811        self.inner.inner
812    }
813
814    /// Creates a raw poitner from this pointer.
815    ///
816    /// # Examples
817    ///
818    /// ```
819    /// use my_ecs::ds::{NonNullExt, ManagedConstPtr};
820    ///
821    /// let mut v = 0;
822    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
823    /// let ptr = unsafe { ManagedConstPtr::new(nne) };
824    /// assert_eq!(ptr.as_ptr(), nne.as_ptr());
825    /// ```
826    #[inline]
827    pub fn as_ptr(&self) -> *const T {
828        self.inner.as_ptr().cast_const()
829    }
830
831    /// Converts the pointer into a shared reference.
832    ///
833    /// Note that trace of the address by `check` feature ends by consuming the
834    /// pointer.
835    ///
836    /// # Examples
837    ///
838    /// ```
839    /// use my_ecs::ds::{NonNullExt, ManagedConstPtr};
840    ///
841    /// let mut v = 0;
842    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
843    /// let ptr = unsafe { ManagedConstPtr::new(nne) };
844    /// assert_eq!(ptr.into_ref(), &0);
845    /// ```
846    #[inline]
847    pub fn into_ref<'a>(self) -> &'a T {
848        let inner = self.as_nonnullext();
849
850        #[cfg(feature = "check")]
851        drop(self);
852
853        // Safety: Managed pointer.
854        unsafe { inner.as_ref() }
855    }
856
857    /// Casts the pointer to another type.
858    ///
859    /// This method doesn't break the trace of the address by `check` feature.
860    /// But internal type information is reset. See [`NonNullExt::cast`].
861    ///
862    /// # Examples
863    ///
864    /// ```
865    /// use my_ecs::ds::{NonNullExt, ManagedConstPtr};
866    ///
867    /// let mut v = 0x1234_5678;
868    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
869    /// let ptr = unsafe { ManagedConstPtr::new(nne) };
870    ///
871    /// let ptr = ptr.cast::<[u8; 4]>();
872    /// let ref_v = ptr.into_ref();
873    /// assert_eq!(*ref_v, i32::to_ne_bytes(v));
874    /// ```
875    #[inline]
876    pub fn cast<U>(self) -> ManagedConstPtr<U> {
877        let inner = self.as_nonnullext();
878
879        #[cfg(feature = "check")]
880        drop(self);
881
882        // Safety: Nothing has changed except `T` -> `U`.
883        unsafe { ManagedConstPtr::new(inner.cast()) }
884    }
885
886    /// Adds an offset to the pointer then returns the result.
887    ///
888    /// Note that `count` is in units of `T`. For example, `count` = 3 means
889    /// 12 bytes offset if `T` is `i32`.
890    ///
891    /// # Safety
892    ///
893    /// See [`NonNull::add`].
894    ///
895    /// # Examples
896    ///
897    /// ```
898    /// use my_ecs::ds::{NonNullExt, ManagedConstPtr};
899    ///
900    /// let arr: [char; 3] = ['a', 'b', 'c'];
901    /// let nne = NonNullExt::new(arr.as_ptr().cast_mut()).unwrap();
902    /// let ptr = unsafe { ManagedConstPtr::new(nne) };
903    ///
904    /// unsafe {
905    ///     assert_eq!(*ptr.add(1), 'b');
906    ///     assert_eq!(*ptr.add(2), 'c');
907    /// }
908    /// ```
909    #[inline]
910    pub unsafe fn add(self, count: usize) -> Self
911    where
912        T: Sized,
913    {
914        Self {
915            inner: unsafe { self.inner.add(count) },
916            #[cfg(feature = "check")]
917            is_trace: self.is_trace,
918        }
919    }
920
921    /// Subtracts an offset from the pointer then returns the result.
922    ///
923    /// Note that `count` is in units of `T`. For example, `count` = 3 means
924    /// 12 bytes offset if `T` is `i32`.
925    ///
926    /// # Safety
927    ///
928    /// See [`NonNull::sub`].
929    ///
930    /// # Examples
931    ///
932    /// ```
933    /// use my_ecs::ds::{NonNullExt, ManagedConstPtr};
934    ///
935    /// let arr: [char; 3] = ['a', 'b', 'c'];
936    /// let nne = NonNullExt::new((&arr[2] as *const char).cast_mut()).unwrap();
937    /// let ptr = unsafe { ManagedConstPtr::new(nne) };
938    ///
939    /// unsafe {
940    ///     assert_eq!(*ptr.sub(1), 'b');
941    ///     assert_eq!(*ptr.sub(2), 'a');
942    /// }
943    /// ```
944    #[inline]
945    pub unsafe fn sub(self, count: usize) -> Self
946    where
947        T: Sized,
948    {
949        Self {
950            inner: unsafe { self.inner.sub(count) },
951            #[cfg(feature = "check")]
952            is_trace: self.is_trace,
953        }
954    }
955}
956
957#[cfg(feature = "check")]
958impl<T: ?Sized> Drop for ManagedConstPtr<T> {
959    fn drop(&mut self) {
960        if self.is_trace {
961            debug::remove_ptr(*self.inner);
962        }
963    }
964}
965
966impl<T: ?Sized> Deref for ManagedConstPtr<T> {
967    type Target = T;
968
969    #[inline]
970    fn deref(&self) -> &Self::Target {
971        // Safety: We assume that the pointer is valid by the constructor.
972        unsafe { self.inner.as_ref() }
973    }
974}
975
976impl<T: ?Sized> PartialEq for ManagedConstPtr<T> {
977    #[allow(ambiguous_wide_pointer_comparisons)]
978    #[inline]
979    fn eq(&self, other: &Self) -> bool {
980        self.as_ptr() == other.as_ptr()
981    }
982}
983
984impl<T: ?Sized> Eq for ManagedConstPtr<T> {}
985
986impl<T: ?Sized> PartialOrd for ManagedConstPtr<T> {
987    #[inline]
988    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
989        Some(self.cmp(other))
990    }
991}
992
993impl<T: ?Sized> Ord for ManagedConstPtr<T> {
994    #[allow(ambiguous_wide_pointer_comparisons)]
995    #[inline]
996    fn cmp(&self, other: &Self) -> cmp::Ordering {
997        self.as_ptr().cmp(&other.as_ptr())
998    }
999}
1000
1001impl<T: ?Sized> hash::Hash for ManagedConstPtr<T> {
1002    #[inline]
1003    fn hash<H: hash::Hasher>(&self, state: &mut H) {
1004        self.inner.hash(state)
1005    }
1006}
1007
1008impl<T: ?Sized> Clone for ManagedConstPtr<T> {
1009    #[inline]
1010    fn clone(&self) -> Self {
1011        #[cfg(feature = "check")]
1012        {
1013            Self {
1014                inner: self.inner,
1015                is_trace: self.is_trace,
1016            }
1017        }
1018
1019        #[cfg(not(feature = "check"))]
1020        *self
1021    }
1022}
1023
1024// It's pointer. We can copy it regardless of T.
1025#[cfg(not(feature = "check"))]
1026impl<T: ?Sized> Copy for ManagedConstPtr<T> {}
1027
1028/// A wrapper of [`NonNullExt`] that can be used to manage a mutable pointer.
1029///
1030/// When the `check` feature is enabled, the crate tracks whether
1031/// [`ManagedMutPtr`] or [`ManagedConstPtr`] that has the same address is being
1032/// created while the pointer is alive. This could be useful when you need extra
1033/// debugging facility than `NonNullExt`.
1034///
1035/// # Safety
1036///
1037/// The pointer is used as a mutable reference without unsafe function such as
1038/// [`NonNull::as_mut`] because the pointer is completely managed. Therefore,
1039/// You must make sure that the pointer will not violate any conditions of
1040/// `Pointer to reference conversion` in [`std::ptr`] document.
1041pub struct ManagedMutPtr<T: ?Sized> {
1042    inner: NonNullExt<T>,
1043    #[cfg(feature = "check")]
1044    is_trace: bool,
1045}
1046
1047impl<T: ?Sized> fmt::Debug for ManagedMutPtr<T> {
1048    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1049        self.inner.fmt(f)
1050    }
1051}
1052
1053unsafe impl<T: ?Sized + Send> Send for ManagedMutPtr<T> {}
1054
1055impl<T: ?Sized> ManagedMutPtr<T> {
1056    /// Creates a [`ManagedMutPtr`] from the given pointer.
1057    ///
1058    /// # Safety
1059    ///
1060    /// See [`ManagedMutPtr`] safety section.
1061    ///
1062    /// # Examples
1063    ///
1064    /// ```
1065    /// use my_ecs::ds::{NonNullExt, ManagedMutPtr};
1066    ///
1067    /// let mut v = 0;
1068    /// let ptr = NonNullExt::new(&mut v as *mut i32).unwrap();
1069    /// let ptr = unsafe { ManagedMutPtr::new(ptr) };
1070    /// ```
1071    #[inline]
1072    pub unsafe fn new(ptr: NonNullExt<T>) -> Self {
1073        // Tracks the address because `is_trace` is true.
1074        #[cfg(feature = "check")]
1075        {
1076            debug::insert_mut_ptr(ptr);
1077        }
1078
1079        Self {
1080            inner: ptr,
1081            #[cfg(feature = "check")]
1082            is_trace: true,
1083        }
1084    }
1085
1086    /// Creates a [`ManagedMutPtr`] that is dangling, but well-aligned.
1087    ///
1088    /// In many Rust functions, they require aligned pointers even if they are
1089    /// some trash values. This function will be usuful in that cases.
1090    ///
1091    /// # Examples
1092    ///
1093    /// ```
1094    /// use my_ecs::ds::ManagedMutPtr;
1095    ///
1096    /// let dangling = ManagedMutPtr::<i32>::dangling();
1097    /// ```
1098    #[inline]
1099    pub const fn dangling() -> Self
1100    where
1101        T: Sized,
1102    {
1103        Self {
1104            inner: NonNullExt::dangling(),
1105            #[cfg(feature = "check")]
1106            is_trace: false,
1107        }
1108    }
1109
1110    /// Returns true if the pointer is dangling.
1111    ///
1112    /// # Examples
1113    ///
1114    /// ```
1115    /// use my_ecs::ds::ManagedMutPtr;
1116    ///
1117    /// let dangling = ManagedMutPtr::<i32>::dangling();
1118    /// assert!(dangling.is_dangling());
1119    /// ```
1120    #[inline]
1121    pub fn is_dangling(&self) -> bool
1122    where
1123        T: Sized,
1124    {
1125        self == &Self::dangling()
1126    }
1127
1128    /// Creates a [`NonNullExt`] from this pointer.
1129    ///
1130    /// # Examples
1131    ///
1132    /// ```
1133    /// use my_ecs::ds::{NonNullExt, ManagedMutPtr};
1134    ///
1135    /// let mut v = 0;
1136    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
1137    /// let ptr = unsafe { ManagedMutPtr::new(nne) };
1138    /// assert_eq!(ptr.as_nonnullext(), nne);
1139    /// ```
1140    #[inline]
1141    pub fn as_nonnullext(&self) -> NonNullExt<T> {
1142        self.inner
1143    }
1144
1145    /// Creates a [`NonNull`] from this pointer.
1146    ///
1147    /// # Examples
1148    ///
1149    /// ```
1150    /// use my_ecs::ds::{NonNullExt, ManagedMutPtr};
1151    ///
1152    /// let mut v = 0;
1153    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
1154    /// let ptr = unsafe { ManagedMutPtr::new(nne) };
1155    /// assert_eq!(ptr.as_nonnull(), *nne);
1156    /// ```
1157    #[inline]
1158    pub fn as_nonnull(&self) -> NonNull<T> {
1159        self.inner.inner
1160    }
1161
1162    /// Creates a raw poitner from this pointer.
1163    ///
1164    /// # Examples
1165    ///
1166    /// ```
1167    /// use my_ecs::ds::{NonNullExt, ManagedMutPtr};
1168    ///
1169    /// let mut v = 0;
1170    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
1171    /// let ptr = unsafe { ManagedMutPtr::new(nne) };
1172    /// assert_eq!(ptr.as_ptr(), nne.as_ptr());
1173    /// ```
1174    #[inline]
1175    pub fn as_ptr(&self) -> *mut T {
1176        self.inner.as_ptr()
1177    }
1178
1179    /// Converts the pointer into a mutable reference.
1180    ///
1181    /// Note that trace of the address by `check` feature ends by consuming the
1182    /// pointer.
1183    ///
1184    /// # Examples
1185    ///
1186    /// ```
1187    /// use my_ecs::ds::{NonNullExt, ManagedMutPtr};
1188    ///
1189    /// let mut v = 0;
1190    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
1191    /// let ptr = unsafe { ManagedMutPtr::new(nne) };
1192    /// assert_eq!(ptr.into_mut(), &0);
1193    /// ```
1194    #[inline]
1195    pub fn into_mut<'a>(self) -> &'a mut T {
1196        let mut inner = self.as_nonnullext();
1197
1198        #[cfg(feature = "check")]
1199        drop(self);
1200
1201        // Safety: Managed pointer.
1202        unsafe { inner.as_mut() }
1203    }
1204
1205    /// Casts the pointer to another type.
1206    ///
1207    /// This method doesn't break the trace of the address by `check` feature.
1208    /// But internal type information is reset. See [`NonNullExt::cast`].
1209    ///
1210    /// # Examples
1211    ///
1212    /// ```
1213    /// use my_ecs::ds::{NonNullExt, ManagedMutPtr};
1214    ///
1215    /// let mut v = 0x1234_5678;
1216    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
1217    /// let ptr = unsafe { ManagedMutPtr::new(nne) };
1218    ///
1219    /// let ptr = ptr.cast::<[u8; 4]>();
1220    /// let ref_v = ptr.into_mut();
1221    /// assert_eq!(*ref_v, i32::to_ne_bytes(v));
1222    /// ```
1223    #[inline]
1224    pub fn cast<U>(self) -> ManagedMutPtr<U> {
1225        let inner = self.as_nonnullext();
1226
1227        #[cfg(feature = "check")]
1228        drop(self);
1229
1230        // Safety: Nothing has changed except `T` -> `U`.
1231        unsafe { ManagedMutPtr::new(inner.cast()) }
1232    }
1233
1234    /// Changes constness without changing the type.
1235    ///
1236    /// # Examples
1237    ///
1238    /// ```
1239    /// use my_ecs::ds::{NonNullExt, ManagedMutPtr};
1240    ///
1241    /// let mut v = 0;
1242    /// let nne = NonNullExt::new(&mut v as *mut i32).unwrap();
1243    /// let ptr = unsafe { ManagedMutPtr::new(nne) };
1244    /// let ptr = ptr.cast_const();
1245    /// ```
1246    #[inline]
1247    pub fn cast_const(self) -> ManagedConstPtr<T> {
1248        let inner = self.as_nonnullext();
1249
1250        #[cfg(feature = "check")]
1251        drop(self);
1252
1253        // Safety: Nothing has changed except `Mut` -> `Const`.
1254        unsafe { ManagedConstPtr::new(inner) }
1255    }
1256
1257    /// Adds an offset to the pointer then returns the result.
1258    ///
1259    /// Note that `count` is in units of `T`. For example, `count` = 3 means
1260    /// 12 bytes offset if `T` is `i32`.
1261    ///
1262    /// # Safety
1263    ///
1264    /// See [`NonNull::add`].
1265    ///
1266    /// # Examples
1267    ///
1268    /// ```
1269    /// use my_ecs::ds::{NonNullExt, ManagedMutPtr};
1270    ///
1271    /// let arr: [char; 2] = ['a', 'b'];
1272    /// let nne = NonNullExt::new(arr.as_ptr().cast_mut()).unwrap();
1273    /// let ptr = unsafe { ManagedMutPtr::new(nne) };
1274    /// unsafe { assert_eq!(*ptr.add(1), 'b') };
1275    /// ```
1276    #[inline]
1277    pub unsafe fn add(self, count: usize) -> Self
1278    where
1279        T: Sized,
1280    {
1281        Self {
1282            inner: unsafe { self.inner.add(count) },
1283            #[cfg(feature = "check")]
1284            is_trace: self.is_trace,
1285        }
1286    }
1287
1288    /// Subtracts an offset from the pointer then returns the result.
1289    ///
1290    /// Note that `count` is in units of `T`. For example, `count` = 3 means
1291    /// 12 bytes offset if `T` is `i32`.
1292    ///
1293    /// # Safety
1294    ///
1295    /// See [`NonNull::sub`].
1296    ///
1297    /// # Examples
1298    ///
1299    /// ```
1300    /// use my_ecs::ds::{NonNullExt, ManagedMutPtr};
1301    ///
1302    /// let arr: [char; 2] = ['a', 'b'];
1303    /// let nne = NonNullExt::new((&arr[1] as *const char).cast_mut()).unwrap();
1304    /// let ptr = unsafe { ManagedMutPtr::new(nne) };
1305    ///
1306    /// unsafe { assert_eq!(*ptr.sub(1), 'a') };
1307    /// ```
1308    #[inline]
1309    pub unsafe fn sub(self, count: usize) -> Self
1310    where
1311        T: Sized,
1312    {
1313        Self {
1314            inner: unsafe { self.inner.sub(count) },
1315            #[cfg(feature = "check")]
1316            is_trace: self.is_trace,
1317        }
1318    }
1319}
1320
1321#[cfg(feature = "check")]
1322impl<T: ?Sized> Drop for ManagedMutPtr<T> {
1323    fn drop(&mut self) {
1324        if self.is_trace {
1325            debug::remove_ptr(*self.inner);
1326        }
1327    }
1328}
1329
1330impl<T: ?Sized> Deref for ManagedMutPtr<T> {
1331    type Target = T;
1332
1333    #[inline]
1334    fn deref(&self) -> &Self::Target {
1335        // Safety: We assume that the pointer is valid by the constructor.
1336        unsafe { self.inner.as_ref() }
1337    }
1338}
1339
1340impl<T: ?Sized> DerefMut for ManagedMutPtr<T> {
1341    #[inline]
1342    fn deref_mut(&mut self) -> &mut Self::Target {
1343        // Safety: We assume that the pointer is valid by the constructor.
1344        unsafe { self.inner.as_mut() }
1345    }
1346}
1347
1348impl<T: ?Sized> PartialEq for ManagedMutPtr<T> {
1349    #[allow(ambiguous_wide_pointer_comparisons)]
1350    #[inline]
1351    fn eq(&self, other: &Self) -> bool {
1352        self.as_ptr() == other.as_ptr()
1353    }
1354}
1355
1356impl<T: ?Sized> Eq for ManagedMutPtr<T> {}
1357
1358impl<T: ?Sized> PartialOrd for ManagedMutPtr<T> {
1359    #[inline]
1360    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
1361        Some(self.cmp(other))
1362    }
1363}
1364
1365impl<T: ?Sized> Ord for ManagedMutPtr<T> {
1366    #[allow(ambiguous_wide_pointer_comparisons)]
1367    #[inline]
1368    fn cmp(&self, other: &Self) -> cmp::Ordering {
1369        self.as_ptr().cmp(&other.as_ptr())
1370    }
1371}
1372
1373impl<T: ?Sized> hash::Hash for ManagedMutPtr<T> {
1374    #[inline]
1375    fn hash<H: hash::Hasher>(&self, state: &mut H) {
1376        self.inner.hash(state)
1377    }
1378}
1379
1380// ManagedMutPtr is not a pure pointer unlike NonNull.
1381// It can be dereferenced as shared or mutable reference without need for unsafe block.
1382// That means it's more like a mutable reference.
1383// So, we don't implement Clone and Copy for it.
1384// impl<T: ?Sized> Clone for ManagedMutPtr<T> {..}
1385// impl<T: ?Sized> Copy for ManagedMutPtr<T> {..}
1386
1387#[cfg(feature = "check")]
1388mod debug {
1389    use super::*;
1390    use dashmap::DashMap;
1391    use std::{mem, sync::LazyLock};
1392
1393    enum RefCount {
1394        Shared(u16),
1395        Exclusive,
1396    }
1397
1398    static RC_MAP: LazyLock<DashMap<[usize; 2], RefCount>> = LazyLock::new(DashMap::new);
1399
1400    const MAX_RC: u16 = 256;
1401
1402    fn create_key<T: ?Sized>(ptr: NonNull<T>) -> [usize; 2] {
1403        const PTR_SIZE: usize = size_of::<*const ()>();
1404        // TODO: Wide pointer size may change in the future.
1405        // See https://doc.rust-lang.org/reference/type-layout.html#pointers-and-references-layout
1406        const WIDE_PTR_SIZE: usize = PTR_SIZE * 2;
1407
1408        const _: () = {
1409            assert!(PTR_SIZE == size_of::<usize>());
1410            assert!(WIDE_PTR_SIZE == size_of::<[usize; 2]>());
1411        };
1412
1413        match size_of_val(&ptr) {
1414            PTR_SIZE => [0, ptr.as_ptr() as *mut () as usize],
1415            WIDE_PTR_SIZE => {
1416                // Safety: We checked the size.
1417                unsafe { mem::transmute_copy(&ptr) }
1418            }
1419            _ => unimplemented!(),
1420        }
1421    }
1422
1423    /// Inserts the pointer to the global map.
1424    /// In the map, shared pointer is allowed to be inserted multiple times.
1425    ///
1426    /// # Panics
1427    ///
1428    /// - Panics if insertion count is greater than the limit (256).
1429    /// - Panics if the map contained the pointer as exclusive pointer.
1430    pub(super) fn insert_const_ptr<T: ?Sized>(ptr: NonNullExt<T>) {
1431        let key = create_key(*ptr);
1432        RC_MAP
1433            .entry(key)
1434            .and_modify(|rc| match rc {
1435                RefCount::Shared(cnt) => {
1436                    *cnt += 1;
1437                    assert!(*cnt <= MAX_RC, "too many ManagedConstPtr");
1438                }
1439                RefCount::Exclusive => {
1440                    panic!("`{ptr:?}` cannot become managed shared pointer because it's already managed as a mutable pointer");
1441                }
1442            })
1443            .or_insert(RefCount::Shared(1));
1444    }
1445
1446    /// Inserts the pointer to the global map.
1447    /// In the map, exclusive pointer is not allowed to be inserted multiple times.
1448    /// To insert the same pointer, you must remove the pointer first.
1449    ///
1450    /// Note, however, that zero-sized `T` is considered shared pointer.
1451    /// It means the pointer is allowed to be inserted many times.
1452    ///
1453    /// # Panics
1454    ///
1455    /// Panics if the map contained the pointer.
1456    pub(super) fn insert_mut_ptr<T: ?Sized>(ptr: NonNullExt<T>) {
1457        // If `T` is a zero-sized type, then it's good to be allowed to have
1458        // the same pointers because they do not mutate the same data.
1459        // It can be considered as a const pointer.
1460        //
1461        // Safety: Even if it's aliased, we do not read the data here.
1462        if unsafe { size_of_val(ptr.as_ref()) } == 0 {
1463            insert_const_ptr(ptr);
1464            return;
1465        }
1466
1467        let key = create_key(*ptr);
1468        RC_MAP
1469            .entry(key)
1470            .and_modify(|rc| match rc {
1471                RefCount::Shared(_) => {
1472                    panic!("`{ptr:?}` cannot become managed mutable pointer because it's already managed as a shared pointer: {:#0x}", ptr.as_ptr() as *mut u8 as usize);
1473                }
1474                RefCount::Exclusive => {
1475                    panic!("`{ptr:?}` cannot become managed mutable pointer because it's already managed as a mutable pointer: {:#0x}", ptr.as_ptr() as *mut u8 as usize);
1476                }
1477            })
1478            .or_insert(RefCount::Exclusive);
1479    }
1480
1481    pub(super) fn remove_ptr<T: ?Sized>(ptr: NonNull<T>) {
1482        let key = create_key(ptr);
1483        assert!(
1484            RC_MAP.contains_key(&key),
1485            "cannot find pointer in the RC_MAP"
1486        );
1487        RC_MAP.remove_if_mut(&key, |_, rc| match rc {
1488            RefCount::Shared(cnt) => {
1489                *cnt -= 1;
1490                *cnt == 0
1491            }
1492            RefCount::Exclusive => true,
1493        });
1494    }
1495}