1#![no_std]
100
101use core::{
102 cmp::Ordering,
103 fmt::{self, Debug, Display},
104 hash::{Hash, Hasher},
105 marker::PhantomData,
106 ops::{Deref, DerefMut, Range, RangeFrom, RangeFull, RangeTo},
107 pin::{pin, Pin},
108 ptr::NonNull,
109 slice,
110 str::Chars,
111};
112
113#[cfg(feature = "alloc")]
114extern crate alloc;
115
116#[cfg(feature = "std")]
117extern crate std;
118
119#[cfg(feature = "derive")]
120pub use temp_inst_derive::{TempRepr, TempReprMut, TempReprMutChk};
121
122use mapped::*;
123
124#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
134pub struct TempInst<'a, T: TempRepr + 'a>(T, PhantomData<T::Shared<'a>>);
135
136impl<'a, T: TempRepr> TempInst<'a, T> {
137 #[must_use]
143 pub fn new(obj: T::Shared<'a>) -> Self {
144 unsafe { TempInst(T::new_temp(obj), PhantomData) }
146 }
147
148 pub fn call_with<R>(obj: T::Shared<'a>, f: impl FnOnce(&T) -> R) -> R {
154 let inst = Self::new(obj);
155 f(&inst)
156 }
157}
158
159impl<T: TempRepr> Deref for TempInst<'_, T> {
160 type Target = T;
161
162 fn deref(&self) -> &Self::Target {
163 &self.0
164 }
165}
166
167impl<'a, T: TempRepr<Shared<'a>: Default>> Default for TempInst<'a, T> {
168 fn default() -> Self {
169 TempInst::new(Default::default())
170 }
171}
172
173impl<T: TempRepr + Debug> Debug for TempInst<'_, T> {
174 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175 self.0.fmt(f)
176 }
177}
178
179impl<T: TempRepr + Display> Display for TempInst<'_, T> {
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 self.0.fmt(f)
182 }
183}
184
185#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
194pub struct TempInstPin<'a, T: TempReprMut + 'a>(T, PhantomData<T::Mutable<'a>>);
195
196impl<'a, T: TempReprMut> TempInstPin<'a, T> {
197 #[must_use]
215 pub fn new(obj: T::Mutable<'a>) -> Self {
216 unsafe { TempInstPin(T::new_temp_mut(obj), PhantomData) }
218 }
219
220 #[must_use]
224 pub fn deref_pin(self: Pin<&mut Self>) -> Pin<&mut T> {
225 unsafe { self.map_unchecked_mut(|inst| &mut inst.0) }
226 }
227
228 pub fn call_with<R>(obj: T::Mutable<'a>, f: impl FnOnce(Pin<&mut T>) -> R) -> R {
234 let inst = pin!(Self::new(obj));
235 f(inst.deref_pin())
236 }
237}
238
239impl<T: TempReprMut> Deref for TempInstPin<'_, T> {
240 type Target = T;
241
242 fn deref(&self) -> &Self::Target {
243 &self.0
244 }
245}
246
247impl<'a, T: TempReprMut<Mutable<'a>: Default>> Default for TempInstPin<'a, T> {
248 fn default() -> Self {
249 TempInstPin::new(Default::default())
250 }
251}
252
253impl<T: TempReprMut + Debug> Debug for TempInstPin<'_, T> {
254 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
255 self.0.fmt(f)
256 }
257}
258
259impl<T: TempReprMut + Display> Display for TempInstPin<'_, T> {
260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261 self.0.fmt(f)
262 }
263}
264
265#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
273pub struct TempInstMut<'a, T: TempReprMutChk + 'a>(T, T::SwapChkData, PhantomData<T::Mutable<'a>>);
274
275impl<'a, T: TempReprMutChk> TempInstMut<'a, T> {
276 #[must_use]
325 pub unsafe fn new(obj: T::Mutable<'a>) -> Self {
326 let temp = T::new_temp_mut(obj);
328 let chk_data = temp.swap_chk_data();
329 TempInstMut(temp, chk_data, PhantomData)
330 }
331
332 pub fn call_with<R>(obj: T::Mutable<'a>, f: impl FnOnce(&mut T) -> R) -> R {
344 let mut inst = unsafe { Self::new(obj) };
346 f(&mut inst)
347 }
348}
349
350impl<T: TempReprMutChk> Deref for TempInstMut<'_, T> {
351 type Target = T;
352
353 fn deref(&self) -> &Self::Target {
354 &self.0
355 }
356}
357
358impl<T: TempReprMutChk> DerefMut for TempInstMut<'_, T> {
359 fn deref_mut(&mut self) -> &mut Self::Target {
360 &mut self.0
361 }
362}
363
364impl<T: TempReprMutChk<Mutable<'static>: Default>> Default for TempInstMut<'static, T> {
365 fn default() -> Self {
366 unsafe { TempInstMut::new(Default::default()) }
369 }
370}
371
372impl<T: TempReprMutChk + Debug> Debug for TempInstMut<'_, T> {
373 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
374 self.0.fmt(f)
375 }
376}
377
378impl<T: TempReprMutChk + Display> Display for TempInstMut<'_, T> {
379 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
380 self.0.fmt(f)
381 }
382}
383
384impl<T: TempReprMutChk> Drop for TempInstMut<'_, T> {
385 fn drop(&mut self) {
386 if self.0.swap_chk_data() != self.1 {
387 modification_panic();
388 }
389 }
390}
391
392#[cfg(feature = "std")]
393fn modification_panic_fn() {
394 let orig_hook = std::panic::take_hook();
396 std::panic::set_hook(std::boxed::Box::new(move |panic_info| {
397 orig_hook(panic_info);
398 std::process::abort()
399 }));
400 panic!("TempInstMut instance was modified; this is not allowed because it violates safety guarantees");
401}
402
403#[cfg(not(feature = "std"))]
404fn modification_panic_fn() {
405 loop {}
408}
409
410static mut MODIFICATION_PANIC_FN: fn() = modification_panic_fn;
411
412pub unsafe fn set_modification_panic_fn(panic_fn: fn()) {
426 MODIFICATION_PANIC_FN = panic_fn;
427}
428
429fn modification_panic() {
430 unsafe { MODIFICATION_PANIC_FN() }
433}
434
435pub unsafe trait TempRepr {
455 type Shared<'a>
458 where
459 Self: 'a;
460
461 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self;
471
472 fn get(&self) -> Self::Shared<'_>;
475}
476
477pub unsafe trait TempReprMut: TempRepr {
501 type Mutable<'a>
504 where
505 Self: 'a;
506
507 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self;
516
517 fn get_mut(&mut self) -> Self::Mutable<'_>;
520
521 fn get_mut_pinned(self: Pin<&mut Self>) -> Self::Mutable<'_>;
523}
524
525pub unsafe trait TempReprMutChk: TempReprMut {
542 type SwapChkData: PartialEq;
543
544 fn swap_chk_data(&self) -> Self::SwapChkData;
548}
549
550pub trait AlwaysShared: TempRepr {}
552
553unsafe impl<T: AlwaysShared> TempReprMut for T {
556 type Mutable<'a> = Self::Shared<'a> where Self: 'a;
557
558 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self {
559 Self::new_temp(obj)
560 }
561
562 fn get_mut(&mut self) -> Self::Mutable<'_> {
563 self.get()
564 }
565
566 fn get_mut_pinned(self: Pin<&mut Self>) -> Self::Mutable<'_> {
567 self.into_ref().get_ref().get()
568 }
569}
570
571#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
578pub struct SelfRepr<T: Clone>(T);
579
580unsafe impl<T: Clone> TempRepr for SelfRepr<T> {
583 type Shared<'a> = T where Self: 'a;
584
585 unsafe fn new_temp(obj: T) -> Self {
586 SelfRepr(obj)
587 }
588
589 fn get(&self) -> T {
590 self.0.clone()
591 }
592}
593
594impl<T: Clone> AlwaysShared for SelfRepr<T> {}
595
596unsafe impl<T: Clone> TempReprMutChk for SelfRepr<T> {
598 type SwapChkData = ();
599
600 fn swap_chk_data(&self) -> Self::SwapChkData {}
601}
602
603pub struct TempRef<T: ?Sized>(NonNull<T>);
611
612unsafe impl<T: ?Sized> TempRepr for TempRef<T> {
615 type Shared<'a> = &'a T where Self: 'a;
616
617 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
618 TempRef(obj.into())
619 }
620
621 fn get(&self) -> Self::Shared<'_> {
622 unsafe { self.0.as_ref() }
624 }
625}
626
627impl<T: ?Sized> AlwaysShared for TempRef<T> {}
628
629unsafe impl<T: ?Sized> TempReprMutChk for TempRef<T> {
632 type SwapChkData = NonNull<T>;
633
634 fn swap_chk_data(&self) -> Self::SwapChkData {
635 self.0
636 }
637}
638
639impl<T: ?Sized> Deref for TempRef<T> {
640 type Target = T;
641
642 fn deref(&self) -> &Self::Target {
643 self.get()
644 }
645}
646
647impl<T: ?Sized + PartialEq> PartialEq for TempRef<T> {
648 fn eq(&self, other: &Self) -> bool {
649 self.get() == other.get()
650 }
651}
652
653impl<T: ?Sized + Eq> Eq for TempRef<T> {}
654
655impl<T: ?Sized + PartialOrd> PartialOrd for TempRef<T> {
656 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
657 self.get().partial_cmp(other.get())
658 }
659
660 fn lt(&self, other: &Self) -> bool {
661 self.get() < other.get()
662 }
663
664 fn le(&self, other: &Self) -> bool {
665 self.get() <= other.get()
666 }
667
668 fn gt(&self, other: &Self) -> bool {
669 self.get() > other.get()
670 }
671
672 fn ge(&self, other: &Self) -> bool {
673 self.get() >= other.get()
674 }
675}
676
677impl<T: ?Sized + Ord> Ord for TempRef<T> {
678 fn cmp(&self, other: &Self) -> Ordering {
679 self.get().cmp(other.get())
680 }
681}
682
683impl<T: ?Sized + Hash> Hash for TempRef<T> {
684 fn hash<H: Hasher>(&self, state: &mut H) {
685 self.get().hash(state);
686 }
687}
688
689impl<T: ?Sized + Debug> Debug for TempRef<T> {
690 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
691 self.get().fmt(f)
692 }
693}
694
695impl<T: ?Sized + Display> Display for TempRef<T> {
696 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
697 self.get().fmt(f)
698 }
699}
700
701unsafe impl<T: ?Sized + Sync> Send for TempRef<T> {}
703unsafe impl<T: ?Sized + Sync> Sync for TempRef<T> {}
704
705#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
713pub struct TempRefMut<T: ?Sized>(TempRef<T>, PhantomData<*mut T>);
714
715unsafe impl<T: ?Sized> TempRepr for TempRefMut<T> {
718 type Shared<'a> = &'a T where Self: 'a;
719
720 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
721 TempRefMut(TempRef::new_temp(obj), PhantomData)
722 }
723
724 fn get(&self) -> Self::Shared<'_> {
725 self.0.get()
726 }
727}
728
729unsafe impl<T: ?Sized> TempReprMut for TempRefMut<T> {
735 type Mutable<'a> = &'a mut T where Self: 'a;
736
737 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self {
738 TempRefMut(TempRef(obj.into()), PhantomData)
739 }
740
741 fn get_mut(&mut self) -> Self::Mutable<'_> {
742 unsafe { self.0 .0.as_mut() }
744 }
745
746 fn get_mut_pinned(mut self: Pin<&mut Self>) -> Self::Mutable<'_> {
747 unsafe { self.0 .0.as_mut() }
749 }
750}
751
752unsafe impl<T: ?Sized> TempReprMutChk for TempRefMut<T> {
755 type SwapChkData = NonNull<T>;
756
757 fn swap_chk_data(&self) -> Self::SwapChkData {
758 self.0.swap_chk_data()
759 }
760}
761
762impl<T: ?Sized> Deref for TempRefMut<T> {
763 type Target = T;
764
765 fn deref(&self) -> &Self::Target {
766 self.get()
767 }
768}
769
770impl<T: ?Sized> DerefMut for TempRefMut<T> {
771 fn deref_mut(&mut self) -> &mut Self::Target {
772 self.get_mut()
773 }
774}
775
776impl<T: ?Sized + Debug> Debug for TempRefMut<T> {
777 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
778 self.get().fmt(f)
779 }
780}
781
782impl<T: ?Sized + Display> Display for TempRefMut<T> {
783 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
784 self.get().fmt(f)
785 }
786}
787
788unsafe impl<T: ?Sized + Send> Send for TempRefMut<T> {}
790unsafe impl<T: ?Sized + Sync> Sync for TempRefMut<T> {}
791
792#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
798pub struct TempRefPin<T: ?Sized>(TempRefMut<T>);
799
800unsafe impl<T: ?Sized> TempRepr for TempRefPin<T> {
803 type Shared<'a> = &'a T where Self: 'a;
804
805 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
806 TempRefPin(TempRefMut::new_temp(obj))
807 }
808
809 fn get(&self) -> Self::Shared<'_> {
810 self.0.get()
811 }
812}
813
814unsafe impl<T: ?Sized> TempReprMut for TempRefPin<T> {
820 type Mutable<'a> = Pin<&'a mut T> where Self: 'a;
821
822 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self {
823 TempRefPin(TempRefMut::new_temp_mut(obj.get_unchecked_mut()))
826 }
827
828 fn get_mut(&mut self) -> Self::Mutable<'_> {
829 unsafe { Pin::new_unchecked(self.0.get_mut()) }
831 }
832
833 fn get_mut_pinned(self: Pin<&mut Self>) -> Self::Mutable<'_> {
834 unsafe { Pin::new_unchecked(self.map_unchecked_mut(|temp| &mut temp.0).get_mut_pinned()) }
836 }
837}
838
839unsafe impl<T: ?Sized> TempReprMutChk for TempRefPin<T> {
842 type SwapChkData = NonNull<T>;
843
844 fn swap_chk_data(&self) -> Self::SwapChkData {
845 self.0.swap_chk_data()
846 }
847}
848
849impl<T: ?Sized> Deref for TempRefPin<T> {
850 type Target = T;
851
852 fn deref(&self) -> &Self::Target {
853 self.get()
854 }
855}
856
857impl<T: ?Sized + Debug> Debug for TempRefPin<T> {
858 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
859 self.get().fmt(f)
860 }
861}
862
863impl<T: ?Sized + Display> Display for TempRefPin<T> {
864 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
865 self.get().fmt(f)
866 }
867}
868
869#[cfg(feature = "alloc")]
875pub enum TempCow<T: ?Sized + alloc::borrow::ToOwned> {
876 Borrowed(TempRef<T>),
877 Owned(T::Owned),
878}
879
880#[cfg(feature = "alloc")]
881unsafe impl<T: ?Sized + alloc::borrow::ToOwned<Owned: Clone>> TempRepr for TempCow<T> {
882 type Shared<'a> = alloc::borrow::Cow<'a, T> where Self: 'a;
883
884 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
885 match obj {
886 alloc::borrow::Cow::Borrowed(obj) => TempCow::Borrowed(TempRef::new_temp(obj)),
887 alloc::borrow::Cow::Owned(obj) => TempCow::Owned(obj),
888 }
889 }
890
891 fn get(&self) -> Self::Shared<'_> {
892 match self {
893 TempCow::Borrowed(temp) => alloc::borrow::Cow::Borrowed(temp.get()),
894 TempCow::Owned(temp) => alloc::borrow::Cow::Owned(temp.clone()),
895 }
896 }
897}
898
899#[cfg(feature = "alloc")]
900impl<T: ?Sized + alloc::borrow::ToOwned<Owned: Clone>> AlwaysShared for TempCow<T> {}
901
902#[cfg(feature = "alloc")]
905unsafe impl<T: ?Sized + alloc::borrow::ToOwned<Owned: Clone>> TempReprMutChk for TempCow<T> {
906 type SwapChkData = Option<NonNull<T>>;
907
908 fn swap_chk_data(&self) -> Self::SwapChkData {
909 match self {
910 TempCow::Borrowed(temp) => Some(temp.swap_chk_data()),
911 TempCow::Owned(_) => None,
912 }
913 }
914}
915
916unsafe impl<T: TempRepr> TempRepr for Option<T> {
921 type Shared<'a> = Option<T::Shared<'a>> where Self: 'a;
922
923 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
924 Some(T::new_temp(obj?))
925 }
926
927 fn get(&self) -> Self::Shared<'_> {
928 Some(self.as_ref()?.get())
929 }
930}
931
932unsafe impl<T: TempReprMut> TempReprMut for Option<T> {
933 type Mutable<'a> = Option<T::Mutable<'a>> where Self: 'a;
934
935 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self {
936 Some(T::new_temp_mut(obj?))
937 }
938
939 fn get_mut(&mut self) -> Self::Mutable<'_> {
940 Some(self.as_mut()?.get_mut())
941 }
942
943 fn get_mut_pinned(self: Pin<&mut Self>) -> Self::Mutable<'_> {
944 Some(self.as_pin_mut()?.get_mut_pinned())
945 }
946}
947
948unsafe impl<T: TempReprMutChk> TempReprMutChk for Option<T> {
949 type SwapChkData = Option<T::SwapChkData>;
950
951 fn swap_chk_data(&self) -> Self::SwapChkData {
952 self.as_ref().map(T::swap_chk_data)
953 }
954}
955
956macro_rules! impl_temp_repr_tuple {
961 ($($idx:tt $T:ident),*) => {
962 #[allow(clippy::unused_unit)]
963 unsafe impl<$($T: TempRepr),*> TempRepr for ($($T,)*) {
964 type Shared<'a> = ($($T::Shared<'a>,)*) where Self: 'a;
965
966 #[allow(unused_variables)]
967 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
968 ($($T::new_temp(obj.$idx),)*)
969 }
970
971 fn get(&self) -> Self::Shared<'_> {
972 ($(self.$idx.get(),)*)
973 }
974 }
975
976 #[allow(clippy::unused_unit)]
977 unsafe impl<$($T: TempReprMut),*> TempReprMut for ($($T,)*) {
978 type Mutable<'a> = ($($T::Mutable<'a>,)*) where Self: 'a;
979
980 #[allow(unused_variables)]
981 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self {
982 ($($T::new_temp_mut(obj.$idx),)*)
983 }
984
985 fn get_mut(&mut self) -> Self::Mutable<'_> {
986 ($(self.$idx.get_mut(),)*)
987 }
988
989 #[allow(unused_variables)]
990 fn get_mut_pinned(self: Pin<&mut Self>) -> Self::Mutable<'_> {
991 unsafe {
992 let temp = self.get_unchecked_mut();
993 ($(Pin::new_unchecked(&mut temp.$idx).get_mut_pinned(),)*)
994 }
995 }
996 }
997
998 #[allow(clippy::unused_unit)]
999 unsafe impl<$($T: TempReprMutChk),*> TempReprMutChk for ($($T,)*) {
1000 type SwapChkData = ($($T::SwapChkData,)*);
1001
1002 fn swap_chk_data(&self) -> Self::SwapChkData {
1003 ($(self.$idx.swap_chk_data(),)*)
1004 }
1005 }
1006 };
1007}
1008
1009impl_temp_repr_tuple!();
1010impl_temp_repr_tuple!(0 T0);
1011impl_temp_repr_tuple!(0 T0, 1 T1);
1012impl_temp_repr_tuple!(0 T0, 1 T1, 2 T2);
1013impl_temp_repr_tuple!(0 T0, 1 T1, 2 T2, 3 T3);
1014impl_temp_repr_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4);
1015impl_temp_repr_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5);
1016impl_temp_repr_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6);
1017impl_temp_repr_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7);
1018impl_temp_repr_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8);
1019impl_temp_repr_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9);
1020impl_temp_repr_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10);
1021impl_temp_repr_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9, 10 T10, 11 T11);
1022
1023#[cfg(feature = "either")]
1028unsafe impl<T0: TempRepr, T1: TempRepr> TempRepr for either::Either<T0, T1> {
1029 type Shared<'a> = either::Either<T0::Shared<'a>, T1::Shared<'a>> where Self: 'a;
1030
1031 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
1032 match obj {
1033 either::Either::Left(obj0) => either::Either::Left(T0::new_temp(obj0)),
1034 either::Either::Right(obj1) => either::Either::Right(T1::new_temp(obj1)),
1035 }
1036 }
1037
1038 fn get(&self) -> Self::Shared<'_> {
1039 match self {
1040 either::Either::Left(self0) => either::Either::Left(self0.get()),
1041 either::Either::Right(self1) => either::Either::Right(self1.get()),
1042 }
1043 }
1044}
1045
1046#[cfg(feature = "either")]
1047unsafe impl<T0: TempReprMut, T1: TempReprMut> TempReprMut for either::Either<T0, T1> {
1048 type Mutable<'a> = either::Either<T0::Mutable<'a>, T1::Mutable<'a>> where Self: 'a;
1049
1050 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self {
1051 match obj {
1052 either::Either::Left(obj0) => either::Either::Left(T0::new_temp_mut(obj0)),
1053 either::Either::Right(obj1) => either::Either::Right(T1::new_temp_mut(obj1)),
1054 }
1055 }
1056
1057 fn get_mut(&mut self) -> Self::Mutable<'_> {
1058 match self {
1059 either::Either::Left(self0) => either::Either::Left(self0.get_mut()),
1060 either::Either::Right(self1) => either::Either::Right(self1.get_mut()),
1061 }
1062 }
1063
1064 fn get_mut_pinned(self: Pin<&mut Self>) -> Self::Mutable<'_> {
1065 match self.as_pin_mut() {
1066 either::Either::Left(self0) => either::Either::Left(self0.get_mut_pinned()),
1067 either::Either::Right(self1) => either::Either::Right(self1.get_mut_pinned()),
1068 }
1069 }
1070}
1071
1072#[cfg(feature = "either")]
1073unsafe impl<T0: TempReprMutChk, T1: TempReprMutChk> TempReprMutChk for either::Either<T0, T1> {
1074 type SwapChkData = either::Either<T0::SwapChkData, T1::SwapChkData>;
1075
1076 fn swap_chk_data(&self) -> Self::SwapChkData {
1077 match self {
1078 either::Either::Left(self0) => either::Either::Left(self0.swap_chk_data()),
1079 either::Either::Right(self1) => either::Either::Right(self1.swap_chk_data()),
1080 }
1081 }
1082}
1083
1084unsafe impl<T: TempRepr> TempRepr for Range<T> {
1089 type Shared<'a> = Range<T::Shared<'a>> where Self: 'a;
1090
1091 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
1092 T::new_temp(obj.start)..T::new_temp(obj.end)
1093 }
1094
1095 fn get(&self) -> Self::Shared<'_> {
1096 self.start.get()..self.end.get()
1097 }
1098}
1099
1100unsafe impl<T: TempReprMut> TempReprMut for Range<T> {
1101 type Mutable<'a> = Range<T::Mutable<'a>> where Self: 'a;
1102
1103 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self {
1104 T::new_temp_mut(obj.start)..T::new_temp_mut(obj.end)
1105 }
1106
1107 fn get_mut(&mut self) -> Self::Mutable<'_> {
1108 self.start.get_mut()..self.end.get_mut()
1109 }
1110
1111 fn get_mut_pinned(self: Pin<&mut Self>) -> Self::Mutable<'_> {
1112 unsafe {
1113 let temp = self.get_unchecked_mut();
1114 let start = Pin::new_unchecked(&mut temp.start);
1115 let end = Pin::new_unchecked(&mut temp.end);
1116 start.get_mut_pinned()..end.get_mut_pinned()
1117 }
1118 }
1119}
1120
1121unsafe impl<T: TempReprMutChk> TempReprMutChk for Range<T> {
1122 type SwapChkData = Range<T::SwapChkData>;
1123
1124 fn swap_chk_data(&self) -> Self::SwapChkData {
1125 self.start.swap_chk_data()..self.end.swap_chk_data()
1126 }
1127}
1128
1129unsafe impl<T: TempRepr> TempRepr for RangeFrom<T> {
1134 type Shared<'a> = RangeFrom<T::Shared<'a>> where Self: 'a;
1135
1136 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
1137 T::new_temp(obj.start)..
1138 }
1139
1140 fn get(&self) -> Self::Shared<'_> {
1141 self.start.get()..
1142 }
1143}
1144
1145unsafe impl<T: TempReprMut> TempReprMut for RangeFrom<T> {
1146 type Mutable<'a> = RangeFrom<T::Mutable<'a>> where Self: 'a;
1147
1148 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self {
1149 T::new_temp_mut(obj.start)..
1150 }
1151
1152 fn get_mut(&mut self) -> Self::Mutable<'_> {
1153 self.start.get_mut()..
1154 }
1155
1156 fn get_mut_pinned(self: Pin<&mut Self>) -> Self::Mutable<'_> {
1157 unsafe {
1158 self.map_unchecked_mut(|temp| &mut temp.start)
1159 .get_mut_pinned()..
1160 }
1161 }
1162}
1163
1164unsafe impl<T: TempReprMutChk> TempReprMutChk for RangeFrom<T> {
1165 type SwapChkData = RangeFrom<T::SwapChkData>;
1166
1167 fn swap_chk_data(&self) -> Self::SwapChkData {
1168 self.start.swap_chk_data()..
1169 }
1170}
1171
1172unsafe impl<T: TempRepr> TempRepr for RangeTo<T> {
1177 type Shared<'a> = RangeTo<T::Shared<'a>> where Self: 'a;
1178
1179 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
1180 ..T::new_temp(obj.end)
1181 }
1182
1183 fn get(&self) -> Self::Shared<'_> {
1184 ..self.end.get()
1185 }
1186}
1187
1188unsafe impl<T: TempReprMut> TempReprMut for RangeTo<T> {
1189 type Mutable<'a> = RangeTo<T::Mutable<'a>> where Self: 'a;
1190
1191 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self {
1192 ..T::new_temp_mut(obj.end)
1193 }
1194
1195 fn get_mut(&mut self) -> Self::Mutable<'_> {
1196 ..self.end.get_mut()
1197 }
1198
1199 fn get_mut_pinned(self: Pin<&mut Self>) -> Self::Mutable<'_> {
1200 unsafe {
1201 ..self
1202 .map_unchecked_mut(|temp| &mut temp.end)
1203 .get_mut_pinned()
1204 }
1205 }
1206}
1207
1208unsafe impl<T: TempReprMutChk> TempReprMutChk for RangeTo<T> {
1209 type SwapChkData = RangeTo<T::SwapChkData>;
1210
1211 fn swap_chk_data(&self) -> Self::SwapChkData {
1212 ..self.end.swap_chk_data()
1213 }
1214}
1215
1216unsafe impl TempRepr for RangeFull {
1221 type Shared<'a> = RangeFull where Self: 'a;
1222
1223 unsafe fn new_temp(_obj: RangeFull) -> Self {
1224 ..
1225 }
1226
1227 fn get(&self) -> RangeFull {
1228 ..
1229 }
1230}
1231
1232impl AlwaysShared for RangeFull {}
1233
1234unsafe impl TempReprMutChk for RangeFull {
1235 type SwapChkData = RangeFull;
1236
1237 fn swap_chk_data(&self) -> Self::SwapChkData {
1238 ..
1239 }
1240}
1241
1242pub mod mapped {
1249 use super::*;
1250
1251 pub trait HasTempRepr {
1258 type Temp: TempRepr;
1259
1260 type Shared<'a>
1261 where
1262 Self: 'a;
1263
1264 fn shared_to_mapped(obj: Self::Shared<'_>) -> <Self::Temp as TempRepr>::Shared<'_>;
1265
1266 fn mapped_to_shared(mapped: <Self::Temp as TempRepr>::Shared<'_>) -> Self::Shared<'_>;
1267 }
1268
1269 pub trait HasTempReprMut: HasTempRepr<Temp: TempReprMut> {
1270 type Mutable<'a>
1271 where
1272 Self: 'a;
1273
1274 fn mut_to_mapped(obj: Self::Mutable<'_>) -> <Self::Temp as TempReprMut>::Mutable<'_>;
1275
1276 fn mapped_to_mut(mapped: <Self::Temp as TempReprMut>::Mutable<'_>) -> Self::Mutable<'_>;
1277 }
1278
1279 pub trait IsAlwaysShared: HasTempRepr<Temp: AlwaysShared> {}
1280
1281 impl<T: IsAlwaysShared> HasTempReprMut for T {
1282 type Mutable<'a> = Self::Shared<'a> where Self: 'a;
1283
1284 fn mut_to_mapped(obj: Self::Mutable<'_>) -> <Self::Temp as TempReprMut>::Mutable<'_> {
1285 Self::shared_to_mapped(obj)
1286 }
1287
1288 fn mapped_to_mut(mapped: <Self::Temp as TempReprMut>::Mutable<'_>) -> Self::Mutable<'_> {
1289 Self::mapped_to_shared(mapped)
1290 }
1291 }
1292
1293 pub struct MappedTempRepr<T: HasTempRepr>(T::Temp);
1295
1296 unsafe impl<T: HasTempRepr> TempRepr for MappedTempRepr<T> {
1297 type Shared<'a> = T::Shared<'a> where Self: 'a;
1298
1299 unsafe fn new_temp(obj: Self::Shared<'_>) -> Self {
1300 MappedTempRepr(T::Temp::new_temp(T::shared_to_mapped(obj)))
1301 }
1302
1303 fn get(&self) -> Self::Shared<'_> {
1304 T::mapped_to_shared(self.0.get())
1305 }
1306 }
1307
1308 unsafe impl<T: HasTempReprMut> TempReprMut for MappedTempRepr<T> {
1309 type Mutable<'a> = T::Mutable<'a> where Self: 'a;
1310
1311 unsafe fn new_temp_mut(obj: Self::Mutable<'_>) -> Self {
1312 MappedTempRepr(T::Temp::new_temp_mut(T::mut_to_mapped(obj)))
1313 }
1314
1315 fn get_mut(&mut self) -> Self::Mutable<'_> {
1316 T::mapped_to_mut(self.0.get_mut())
1317 }
1318
1319 fn get_mut_pinned(self: Pin<&mut Self>) -> Self::Mutable<'_> {
1320 let temp = unsafe { self.map_unchecked_mut(|temp| &mut temp.0) };
1322 T::mapped_to_mut(temp.get_mut_pinned())
1323 }
1324 }
1325
1326 unsafe impl<T: HasTempReprMut<Temp: TempReprMutChk>> TempReprMutChk for MappedTempRepr<T> {
1327 type SwapChkData = <T::Temp as TempReprMutChk>::SwapChkData;
1328
1329 fn swap_chk_data(&self) -> Self::SwapChkData {
1330 self.0.swap_chk_data()
1331 }
1332 }
1333
1334 impl<T: HasTempRepr> PartialEq for MappedTempRepr<T>
1335 where
1336 for<'a> T::Shared<'a>: PartialEq,
1337 {
1338 fn eq(&self, other: &Self) -> bool {
1339 self.get() == other.get()
1340 }
1341 }
1342
1343 impl<T: HasTempRepr> Eq for MappedTempRepr<T> where for<'a> T::Shared<'a>: Eq {}
1344
1345 impl<T: HasTempRepr> PartialOrd for MappedTempRepr<T>
1346 where
1347 for<'a> T::Shared<'a>: PartialOrd,
1348 {
1349 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1350 self.get().partial_cmp(&other.get())
1351 }
1352
1353 fn lt(&self, other: &Self) -> bool {
1354 self.get() < other.get()
1355 }
1356
1357 fn le(&self, other: &Self) -> bool {
1358 self.get() <= other.get()
1359 }
1360
1361 fn gt(&self, other: &Self) -> bool {
1362 self.get() > other.get()
1363 }
1364
1365 fn ge(&self, other: &Self) -> bool {
1366 self.get() >= other.get()
1367 }
1368 }
1369
1370 impl<T: HasTempRepr> Ord for MappedTempRepr<T>
1371 where
1372 for<'a> T::Shared<'a>: Ord,
1373 {
1374 fn cmp(&self, other: &Self) -> Ordering {
1375 self.get().cmp(&other.get())
1376 }
1377 }
1378
1379 impl<T: HasTempRepr> Hash for MappedTempRepr<T>
1380 where
1381 for<'a> T::Shared<'a>: Hash,
1382 {
1383 fn hash<H: Hasher>(&self, state: &mut H) {
1384 self.get().hash(state);
1385 }
1386 }
1387
1388 impl<T: HasTempRepr> Debug for MappedTempRepr<T>
1389 where
1390 for<'a> T::Shared<'a>: Debug,
1391 {
1392 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1393 self.get().fmt(f)
1394 }
1395 }
1396
1397 impl<T: HasTempRepr> Display for MappedTempRepr<T>
1398 where
1399 for<'a> T::Shared<'a>: Display,
1400 {
1401 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1402 self.get().fmt(f)
1403 }
1404 }
1405
1406 impl<T> HasTempRepr for slice::Iter<'static, T> {
1407 type Temp = TempRef<[T]>;
1408
1409 type Shared<'a> = slice::Iter<'a, T> where Self: 'a;
1410
1411 fn shared_to_mapped(obj: Self::Shared<'_>) -> <Self::Temp as TempRepr>::Shared<'_> {
1412 obj.as_slice()
1413 }
1414
1415 fn mapped_to_shared(mapped: <Self::Temp as TempRepr>::Shared<'_>) -> Self::Shared<'_> {
1416 mapped.iter()
1417 }
1418 }
1419
1420 impl<T> IsAlwaysShared for slice::Iter<'static, T> {}
1421
1422 impl<T> HasTempRepr for slice::IterMut<'static, T> {
1423 type Temp = TempRefMut<[T]>;
1424
1425 type Shared<'a> = slice::Iter<'a, T> where Self: 'a;
1426
1427 fn shared_to_mapped(obj: Self::Shared<'_>) -> <Self::Temp as TempRepr>::Shared<'_> {
1428 obj.as_slice()
1429 }
1430
1431 fn mapped_to_shared(mapped: <Self::Temp as TempRepr>::Shared<'_>) -> Self::Shared<'_> {
1432 mapped.iter()
1433 }
1434 }
1435
1436 impl<T> HasTempReprMut for slice::IterMut<'static, T> {
1437 type Mutable<'a> = slice::IterMut<'a, T> where Self: 'a;
1438
1439 fn mut_to_mapped(obj: Self::Mutable<'_>) -> <Self::Temp as TempReprMut>::Mutable<'_> {
1440 obj.into_slice()
1441 }
1442
1443 fn mapped_to_mut(mapped: <Self::Temp as TempReprMut>::Mutable<'_>) -> Self::Mutable<'_> {
1444 mapped.iter_mut()
1445 }
1446 }
1447
1448 impl HasTempRepr for Chars<'static> {
1449 type Temp = TempRef<str>;
1450
1451 type Shared<'a> = Chars<'a> where Self: 'a;
1452
1453 fn shared_to_mapped(obj: Self::Shared<'_>) -> <Self::Temp as TempRepr>::Shared<'_> {
1454 obj.as_str()
1455 }
1456
1457 fn mapped_to_shared(mapped: <Self::Temp as TempRepr>::Shared<'_>) -> Self::Shared<'_> {
1458 mapped.chars()
1459 }
1460 }
1461
1462 impl IsAlwaysShared for Chars<'static> {}
1463}
1464
1465pub type TempSliceIter<T> = MappedTempRepr<slice::Iter<'static, T>>;
1466pub type TempSliceIterMut<T> = MappedTempRepr<slice::IterMut<'static, T>>;
1467
1468pub type TempChars = MappedTempRepr<Chars<'static>>;
1469
1470#[cfg(test)]
1471mod tests {
1472 use core::mem::swap;
1473
1474 use super::*;
1475
1476 #[cfg(feature = "std")]
1477 fn init_tests() {
1478 static INIT: std::sync::LazyLock<()> = std::sync::LazyLock::new(|| unsafe {
1482 set_modification_panic_fn(|| {
1483 if !std::thread::panicking() {
1484 panic!("TempInstMut instance was modified");
1485 }
1486 })
1487 });
1488 *INIT
1489 }
1490
1491 #[cfg(not(feature = "std"))]
1492 fn init_tests() {}
1493
1494 #[test]
1495 fn temp_ref() {
1496 init_tests();
1497 let mut a = 42;
1498 let a_inst = TempInst::<TempRef<i32>>::new(&a);
1499 let a_ref = a_inst.get();
1500 assert_eq!(*a_ref, 42);
1501 let double = 2 * *a_ref;
1502 assert_eq!(a, 42);
1503 a += 1; assert_eq!(a, 43);
1505 assert_eq!(double, 2 * 42);
1506 }
1507
1508 #[test]
1509 fn temp_ref_call() {
1510 init_tests();
1511 let a = 42;
1512 let double = TempInst::<TempRef<i32>>::call_with(&a, |a_inst| {
1513 let a_ref = a_inst.get();
1514 assert_eq!(*a_ref, 42);
1515 2 * *a_ref
1516 });
1517 assert_eq!(a, 42);
1518 assert_eq!(double, 2 * 42);
1519 }
1520
1521 #[test]
1522 fn temp_ref_call_pair() {
1523 init_tests();
1524 let a = 42;
1525 let b = 23;
1526 let sum = TempInst::<(TempRef<i32>, TempRef<i32>)>::call_with((&a, &b), |a_b_inst| {
1527 let (a_ref, b_ref) = a_b_inst.get();
1528 assert_eq!(*a_ref, 42);
1529 assert_eq!(*b_ref, 23);
1530 *a_ref + *b_ref
1531 });
1532 assert_eq!(a, 42);
1533 assert_eq!(b, 23);
1534 assert_eq!(sum, 42 + 23);
1535 }
1536
1537 #[test]
1538 fn temp_ref_call_mut() {
1539 init_tests();
1540 let mut a = 42;
1541 let double = TempInstMut::<TempRefMut<i32>>::call_with(&mut a, |a_inst| {
1542 let a_ref = a_inst.get_mut();
1543 assert_eq!(*a_ref, 42);
1544 *a_ref += 1;
1545 2 * *a_ref
1546 });
1547 assert_eq!(a, 43);
1548 assert_eq!(double, 2 * 43);
1549 }
1550
1551 #[test]
1552 fn temp_ref_call_pair_mut() {
1553 init_tests();
1554 let mut a = 42;
1555 let mut b = 23;
1556 let sum = TempInstMut::<(TempRefMut<i32>, TempRefMut<i32>)>::call_with(
1557 (&mut a, &mut b),
1558 |a_b_inst| {
1559 let (a_ref, b_ref) = a_b_inst.get_mut();
1560 assert_eq!(*a_ref, 42);
1561 assert_eq!(*b_ref, 23);
1562 *a_ref += 1;
1563 *b_ref -= 2;
1564 *a_ref + *b_ref
1565 },
1566 );
1567 assert_eq!(a, 43);
1568 assert_eq!(b, 21);
1569 assert_eq!(sum, 43 + 21);
1570 }
1571
1572 #[test]
1573 fn temp_ref_call_pair_half_mut() {
1574 init_tests();
1575 let mut a = 42;
1576 let b = 23;
1577 let sum =
1578 TempInstMut::<(TempRefMut<i32>, TempRef<i32>)>::call_with((&mut a, &b), |a_b_inst| {
1579 let (a_ref, b_ref) = a_b_inst.get_mut();
1580 assert_eq!(*a_ref, 42);
1581 assert_eq!(*b_ref, 23);
1582 *a_ref += 1;
1583 *a_ref + *b_ref
1584 });
1585 assert_eq!(a, 43);
1586 assert_eq!(b, 23);
1587 assert_eq!(sum, 43 + 23);
1588 }
1589
1590 #[test]
1591 fn temp_ref_mut_pin() {
1592 init_tests();
1593 let mut a = 42;
1594 let a_inst = pin!(TempInstPin::<TempRefMut<i32>>::new(&mut a));
1595 let a_ref = a_inst.deref_pin().get_mut_pinned();
1596 assert_eq!(*a_ref, 42);
1597 *a_ref += 1;
1598 let double = 2 * *a_ref;
1599 assert_eq!(a, 43);
1600 assert_eq!(double, 2 * 43);
1601 }
1602
1603 #[test]
1604 fn temp_ref_mut_call_pin() {
1605 init_tests();
1606 let mut a = 42;
1607 let double = TempInstPin::<TempRefMut<i32>>::call_with(&mut a, |a_inst| {
1608 let a_ref = a_inst.get_mut_pinned();
1609 assert_eq!(*a_ref, 42);
1610 *a_ref += 1;
1611 2 * *a_ref
1612 });
1613 assert_eq!(a, 43);
1614 assert_eq!(double, 2 * 43);
1615 }
1616
1617 #[test]
1618 fn temp_ref_pin_call_pin() {
1619 init_tests();
1620 let mut a = pin!(42);
1621 let double = TempInstPin::<TempRefPin<i32>>::call_with(Pin::as_mut(&mut a), |a_inst| {
1622 let a_ref = a_inst.get_mut_pinned().get_mut();
1623 assert_eq!(*a_ref, 42);
1624 *a_ref += 1;
1625 2 * *a_ref
1626 });
1627 assert_eq!(*a, 43);
1628 assert_eq!(double, 2 * 43);
1629 }
1630
1631 #[cfg(feature = "std")]
1632 #[test]
1633 #[should_panic(expected = "TempInstMut instance was modified")]
1634 fn temp_ref_call_mut_illegal_swap() {
1635 init_tests();
1636 let mut a = 42;
1637 TempInstMut::<TempRefMut<i32>>::call_with(&mut a, |a_inst| {
1638 let mut b = 43;
1639 TempInstMut::<TempRefMut<i32>>::call_with(&mut b, |b_inst| {
1640 swap(a_inst, b_inst);
1641 });
1642 let b_ref = a_inst.get_mut();
1644 assert_ne!(*b_ref, 43);
1645 });
1646 }
1647
1648 #[test]
1649 fn temp_ref_call_mut_swap_zero_size() {
1650 init_tests();
1656 let mut a = ((), ());
1657 TempInstMut::<TempRefMut<()>>::call_with(&mut a.0, |a0_inst| {
1658 TempInstMut::<TempRefMut<()>>::call_with(&mut a.1, |a1_inst| {
1659 swap(a0_inst, a1_inst);
1660 });
1661 let a1_ref = &mut a.1;
1664 let a1_ref_2 = a0_inst.get_mut();
1665 *a1_ref = ();
1666 *a1_ref_2 = ();
1667 });
1668 }
1669
1670 #[cfg(feature = "std")]
1671 #[test]
1672 fn temp_ref_send() {
1673 init_tests();
1674 let a = 42;
1675 let a_inst = TempInst::<TempRef<i32>>::new(&a);
1676 std::thread::scope(|scope| {
1677 let thread = scope.spawn(move || **a_inst);
1678 let result = thread.join().unwrap();
1679 assert_eq!(result, 42);
1680 });
1681 }
1682
1683 #[cfg(feature = "std")]
1684 #[test]
1685 fn temp_ref_sync() {
1686 init_tests();
1687 let a = 42;
1688 let a_inst = TempInst::<TempRef<i32>>::new(&a);
1689 std::thread::scope(|scope| {
1690 let thread = scope.spawn(|| **a_inst);
1691 let result = thread.join().unwrap();
1692 assert_eq!(result, 42);
1693 });
1694 }
1695
1696 #[cfg(feature = "std")]
1697 #[test]
1698 fn temp_ref_pin_send() {
1699 init_tests();
1700 let a = pin!(42);
1701 let a_inst = TempInstPin::<TempRefPin<i32>>::new(a);
1702 std::thread::scope(|scope| {
1703 let thread = scope.spawn(move || **a_inst);
1704 let result = thread.join().unwrap();
1705 assert_eq!(result, 42);
1706 });
1707 }
1708
1709 #[cfg(feature = "std")]
1710 #[test]
1711 fn temp_ref_pin_sync() {
1712 init_tests();
1713 let a = pin!(42);
1714 let a_inst = TempInstPin::<TempRefPin<i32>>::new(a);
1715 std::thread::scope(|scope| {
1716 let thread = scope.spawn(|| **a_inst);
1717 let result = thread.join().unwrap();
1718 assert_eq!(result, 42);
1719 });
1720 }
1721
1722 #[cfg(feature = "std")]
1723 #[test]
1724 fn temp_ref_call_mut_send() {
1725 init_tests();
1726 let mut a = 42;
1727 TempInstMut::<TempRefMut<i32>>::call_with(&mut a, |a_inst| {
1728 std::thread::scope(|scope| {
1729 let thread = scope.spawn(move || **a_inst += 1);
1730 thread.join().unwrap();
1731 })
1732 });
1733 assert_eq!(a, 43);
1734 }
1735
1736 #[cfg(feature = "std")]
1737 #[test]
1738 fn temp_ref_call_mut_sync() {
1739 init_tests();
1740 let mut a = 42;
1741 TempInstMut::<TempRefMut<i32>>::call_with(&mut a, |a_inst| {
1742 std::thread::scope(|scope| {
1743 let thread = scope.spawn(|| **a_inst += 1);
1744 thread.join().unwrap();
1745 })
1746 });
1747 assert_eq!(a, 43);
1748 }
1749}