intuicio_data/managed/
mod.rs

1pub mod gc;
2pub mod value;
3
4use crate::{
5    Finalize,
6    lifetime::{
7        Lifetime, LifetimeLazy, LifetimeRef, LifetimeRefMut, ValueReadAccess, ValueWriteAccess,
8    },
9    managed::value::{DynamicManagedValue, ManagedValue},
10    non_zero_alloc, non_zero_dealloc,
11    type_hash::TypeHash,
12};
13use std::{alloc::Layout, mem::MaybeUninit};
14
15#[derive(Default)]
16pub struct Managed<T> {
17    lifetime: Lifetime,
18    data: T,
19}
20
21impl<T> Managed<T> {
22    pub fn new(data: T) -> Self {
23        Self {
24            lifetime: Default::default(),
25            data,
26        }
27    }
28
29    pub fn new_raw(data: T, lifetime: Lifetime) -> Self {
30        Self { lifetime, data }
31    }
32
33    pub fn into_inner(self) -> (Lifetime, T) {
34        (self.lifetime, self.data)
35    }
36
37    pub fn into_dynamic(self) -> Result<DynamicManaged, Self> {
38        match DynamicManaged::new(self.data) {
39            Ok(value) => Ok(value),
40            Err(data) => Err(Managed {
41                lifetime: self.lifetime,
42                data,
43            }),
44        }
45    }
46
47    pub fn renew(mut self) -> Self {
48        self.lifetime = Lifetime::default();
49        self
50    }
51
52    pub fn lifetime(&self) -> &Lifetime {
53        &self.lifetime
54    }
55
56    pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
57        self.lifetime.read(&self.data)
58    }
59
60    pub fn write(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
61        self.lifetime.write(&mut self.data)
62    }
63
64    pub fn consume(self) -> Result<T, Self> {
65        if self.lifetime.state().is_in_use() {
66            Err(self)
67        } else {
68            Ok(self.data)
69        }
70    }
71
72    pub fn move_into_ref(self, mut target: ManagedRefMut<T>) -> Result<(), Self> {
73        *target.write().unwrap() = self.consume()?;
74        Ok(())
75    }
76
77    pub fn move_into_lazy(self, target: ManagedLazy<T>) -> Result<(), Self> {
78        *target.write().unwrap() = self.consume()?;
79        Ok(())
80    }
81
82    pub fn borrow(&self) -> Option<ManagedRef<T>> {
83        Some(ManagedRef::new(&self.data, self.lifetime.borrow()?))
84    }
85
86    pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
87        Some(ManagedRefMut::new(
88            &mut self.data,
89            self.lifetime.borrow_mut()?,
90        ))
91    }
92
93    pub fn lazy(&mut self) -> ManagedLazy<T> {
94        ManagedLazy::new(&mut self.data, self.lifetime.lazy())
95    }
96
97    /// # Safety
98    pub unsafe fn lazy_immutable(&self) -> ManagedLazy<T> {
99        unsafe {
100            ManagedLazy::new_raw(&self.data as *const T as *mut T, self.lifetime.lazy()).unwrap()
101        }
102    }
103
104    /// # Safety
105    pub unsafe fn map<U>(self, f: impl FnOnce(T) -> U) -> Managed<U> {
106        Managed {
107            lifetime: Default::default(),
108            data: f(self.data),
109        }
110    }
111
112    /// # Safety
113    pub unsafe fn try_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Managed<U>> {
114        f(self.data).map(|data| Managed {
115            lifetime: Default::default(),
116            data,
117        })
118    }
119
120    /// # Safety
121    pub unsafe fn as_ptr(&self) -> *const T {
122        &self.data as _
123    }
124
125    /// # Safety
126    pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
127        &mut self.data as _
128    }
129}
130
131pub struct ManagedRef<T: ?Sized> {
132    lifetime: LifetimeRef,
133    data: *const T,
134}
135
136unsafe impl<T: ?Sized> Send for ManagedRef<T> where T: Send {}
137unsafe impl<T: ?Sized> Sync for ManagedRef<T> where T: Sync {}
138
139impl<T: ?Sized> ManagedRef<T> {
140    pub fn new(data: &T, lifetime: LifetimeRef) -> Self {
141        Self {
142            lifetime,
143            data: data as *const T,
144        }
145    }
146
147    /// # Safety
148    pub unsafe fn new_raw(data: *const T, lifetime: LifetimeRef) -> Option<Self> {
149        if data.is_null() {
150            None
151        } else {
152            Some(Self { lifetime, data })
153        }
154    }
155
156    pub fn make(data: &T) -> (Self, Lifetime) {
157        let result = Lifetime::default();
158        (Self::new(data, result.borrow().unwrap()), result)
159    }
160
161    /// # Safety
162    pub unsafe fn make_raw(data: *const T) -> Option<(Self, Lifetime)> {
163        let result = Lifetime::default();
164        Some((
165            unsafe { Self::new_raw(data, result.borrow().unwrap()) }?,
166            result,
167        ))
168    }
169
170    pub fn into_inner(self) -> (LifetimeRef, *const T) {
171        (self.lifetime, self.data)
172    }
173
174    pub fn into_dynamic(self) -> DynamicManagedRef {
175        unsafe {
176            DynamicManagedRef::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *const u8)
177                .unwrap()
178        }
179    }
180
181    pub fn lifetime(&self) -> &LifetimeRef {
182        &self.lifetime
183    }
184
185    pub fn borrow(&self) -> Option<ManagedRef<T>> {
186        Some(ManagedRef {
187            lifetime: self.lifetime.borrow()?,
188            data: self.data,
189        })
190    }
191
192    /// # Safety
193    pub unsafe fn lazy_immutable(&self) -> ManagedLazy<T> {
194        ManagedLazy {
195            lifetime: self.lifetime.lazy(),
196            data: self.data as *mut T,
197        }
198    }
199
200    pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
201        unsafe { self.lifetime.read_ptr(self.data) }
202    }
203
204    /// # Safety
205    pub unsafe fn map<U>(self, f: impl FnOnce(&T) -> &U) -> ManagedRef<U> {
206        unsafe {
207            let data = f(&*self.data);
208            ManagedRef {
209                lifetime: self.lifetime,
210                data: data as *const U,
211            }
212        }
213    }
214
215    /// # Safety
216    pub unsafe fn try_map<U>(self, f: impl FnOnce(&T) -> Option<&U>) -> Option<ManagedRef<U>> {
217        unsafe {
218            f(&*self.data).map(|data| ManagedRef {
219                lifetime: self.lifetime,
220                data: data as *const U,
221            })
222        }
223    }
224
225    /// # Safety
226    pub unsafe fn as_ptr(&self) -> Option<*const T> {
227        if self.lifetime.exists() {
228            Some(self.data)
229        } else {
230            None
231        }
232    }
233}
234
235impl<T> TryFrom<ManagedValue<T>> for ManagedRef<T> {
236    type Error = ();
237
238    fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
239        match value {
240            ManagedValue::Ref(value) => Ok(value),
241            _ => Err(()),
242        }
243    }
244}
245
246pub struct ManagedRefMut<T: ?Sized> {
247    lifetime: LifetimeRefMut,
248    data: *mut T,
249}
250
251unsafe impl<T: ?Sized> Send for ManagedRefMut<T> where T: Send {}
252unsafe impl<T: ?Sized> Sync for ManagedRefMut<T> where T: Sync {}
253
254impl<T: ?Sized> ManagedRefMut<T> {
255    pub fn new(data: &mut T, lifetime: LifetimeRefMut) -> Self {
256        Self {
257            lifetime,
258            data: data as *mut T,
259        }
260    }
261
262    /// # Safety
263    pub unsafe fn new_raw(data: *mut T, lifetime: LifetimeRefMut) -> Option<Self> {
264        if data.is_null() {
265            None
266        } else {
267            Some(Self { lifetime, data })
268        }
269    }
270
271    pub fn make(data: &mut T) -> (Self, Lifetime) {
272        let result = Lifetime::default();
273        (Self::new(data, result.borrow_mut().unwrap()), result)
274    }
275
276    /// # Safety
277    pub unsafe fn make_raw(data: *mut T) -> Option<(Self, Lifetime)> {
278        let result = Lifetime::default();
279        Some((
280            unsafe { Self::new_raw(data, result.borrow_mut().unwrap()) }?,
281            result,
282        ))
283    }
284
285    pub fn into_inner(self) -> (LifetimeRefMut, *mut T) {
286        (self.lifetime, self.data)
287    }
288
289    pub fn into_dynamic(self) -> DynamicManagedRefMut {
290        unsafe {
291            DynamicManagedRefMut::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *mut u8)
292                .unwrap()
293        }
294    }
295
296    pub fn lifetime(&self) -> &LifetimeRefMut {
297        &self.lifetime
298    }
299
300    pub fn borrow(&self) -> Option<ManagedRef<T>> {
301        Some(ManagedRef {
302            lifetime: self.lifetime.borrow()?,
303            data: self.data,
304        })
305    }
306
307    pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
308        Some(ManagedRefMut {
309            lifetime: self.lifetime.borrow_mut()?,
310            data: self.data,
311        })
312    }
313
314    pub fn lazy(&self) -> ManagedLazy<T> {
315        ManagedLazy {
316            lifetime: self.lifetime.lazy(),
317            data: self.data,
318        }
319    }
320
321    pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
322        unsafe { self.lifetime.read_ptr(self.data) }
323    }
324
325    pub fn write(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
326        unsafe { self.lifetime.write_ptr(self.data) }
327    }
328
329    /// # Safety
330    pub unsafe fn map<U>(self, f: impl FnOnce(&mut T) -> &mut U) -> ManagedRefMut<U> {
331        unsafe {
332            let data = f(&mut *self.data);
333            ManagedRefMut {
334                lifetime: self.lifetime,
335                data: data as *mut U,
336            }
337        }
338    }
339
340    /// # Safety
341    pub unsafe fn try_map<U>(
342        self,
343        f: impl FnOnce(&mut T) -> Option<&mut U>,
344    ) -> Option<ManagedRefMut<U>> {
345        unsafe {
346            f(&mut *self.data).map(|data| ManagedRefMut {
347                lifetime: self.lifetime,
348                data: data as *mut U,
349            })
350        }
351    }
352
353    /// # Safety
354    pub unsafe fn as_ptr(&self) -> Option<*const T> {
355        if self.lifetime.exists() {
356            Some(self.data)
357        } else {
358            None
359        }
360    }
361
362    /// # Safety
363    pub unsafe fn as_mut_ptr(&mut self) -> Option<*mut T> {
364        if self.lifetime.exists() {
365            Some(self.data)
366        } else {
367            None
368        }
369    }
370}
371
372impl<T> TryFrom<ManagedValue<T>> for ManagedRefMut<T> {
373    type Error = ();
374
375    fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
376        match value {
377            ManagedValue::RefMut(value) => Ok(value),
378            _ => Err(()),
379        }
380    }
381}
382
383pub struct ManagedLazy<T: ?Sized> {
384    lifetime: LifetimeLazy,
385    data: *mut T,
386}
387
388unsafe impl<T: ?Sized> Send for ManagedLazy<T> where T: Send {}
389unsafe impl<T: ?Sized> Sync for ManagedLazy<T> where T: Sync {}
390
391impl<T: ?Sized> Clone for ManagedLazy<T> {
392    fn clone(&self) -> Self {
393        Self {
394            lifetime: self.lifetime.clone(),
395            data: self.data,
396        }
397    }
398}
399
400impl<T: ?Sized> ManagedLazy<T> {
401    pub fn new(data: &mut T, lifetime: LifetimeLazy) -> Self {
402        Self {
403            lifetime,
404            data: data as *mut T,
405        }
406    }
407
408    /// # Safety
409    pub unsafe fn new_raw(data: *mut T, lifetime: LifetimeLazy) -> Option<Self> {
410        if data.is_null() {
411            None
412        } else {
413            Some(Self { lifetime, data })
414        }
415    }
416
417    pub fn make(data: &mut T) -> (Self, Lifetime) {
418        let result = Lifetime::default();
419        (Self::new(data, result.lazy()), result)
420    }
421
422    /// # Safety
423    pub unsafe fn make_raw(data: *mut T) -> Option<(Self, Lifetime)> {
424        let result = Lifetime::default();
425        Some((unsafe { Self::new_raw(data, result.lazy()) }?, result))
426    }
427
428    pub fn into_inner(self) -> (LifetimeLazy, *mut T) {
429        (self.lifetime, self.data)
430    }
431
432    pub fn into_dynamic(self) -> DynamicManagedLazy {
433        unsafe {
434            DynamicManagedLazy::new_raw(TypeHash::of::<T>(), self.lifetime, self.data as *mut u8)
435                .unwrap()
436        }
437    }
438
439    pub fn lifetime(&self) -> &LifetimeLazy {
440        &self.lifetime
441    }
442
443    pub fn borrow(&self) -> Option<ManagedRef<T>> {
444        Some(ManagedRef {
445            lifetime: self.lifetime.borrow()?,
446            data: self.data,
447        })
448    }
449
450    pub fn borrow_mut(&mut self) -> Option<ManagedRefMut<T>> {
451        Some(ManagedRefMut {
452            lifetime: self.lifetime.borrow_mut()?,
453            data: self.data,
454        })
455    }
456
457    pub fn read(&'_ self) -> Option<ValueReadAccess<'_, T>> {
458        unsafe { self.lifetime.read_ptr(self.data) }
459    }
460
461    pub fn write(&'_ self) -> Option<ValueWriteAccess<'_, T>> {
462        unsafe { self.lifetime.write_ptr(self.data) }
463    }
464
465    /// # Safety
466    pub unsafe fn map<U>(self, f: impl FnOnce(&mut T) -> &mut U) -> ManagedLazy<U> {
467        unsafe {
468            let data = f(&mut *self.data);
469            ManagedLazy {
470                lifetime: self.lifetime,
471                data: data as *mut U,
472            }
473        }
474    }
475
476    /// # Safety
477    pub unsafe fn try_map<U>(
478        self,
479        f: impl FnOnce(&mut T) -> Option<&mut U>,
480    ) -> Option<ManagedLazy<U>> {
481        unsafe {
482            f(&mut *self.data).map(|data| ManagedLazy {
483                lifetime: self.lifetime,
484                data: data as *mut U,
485            })
486        }
487    }
488
489    /// # Safety
490    pub unsafe fn as_ptr(&self) -> Option<*const T> {
491        if self.lifetime.exists() {
492            Some(self.data)
493        } else {
494            None
495        }
496    }
497
498    /// # Safety
499    pub unsafe fn as_mut_ptr(&self) -> Option<*mut T> {
500        if self.lifetime.exists() {
501            Some(self.data)
502        } else {
503            None
504        }
505    }
506}
507
508impl<T> TryFrom<ManagedValue<T>> for ManagedLazy<T> {
509    type Error = ();
510
511    fn try_from(value: ManagedValue<T>) -> Result<Self, Self::Error> {
512        match value {
513            ManagedValue::Lazy(value) => Ok(value),
514            _ => Err(()),
515        }
516    }
517}
518
519pub struct DynamicManaged {
520    type_hash: TypeHash,
521    lifetime: Lifetime,
522    memory: *mut u8,
523    layout: Layout,
524    finalizer: unsafe fn(*mut ()),
525    drop: bool,
526}
527
528unsafe impl Send for DynamicManaged {}
529unsafe impl Sync for DynamicManaged {}
530
531impl Drop for DynamicManaged {
532    fn drop(&mut self) {
533        if self.drop {
534            unsafe {
535                if self.memory.is_null() {
536                    return;
537                }
538                let data_pointer = self.memory.cast::<()>();
539                (self.finalizer)(data_pointer);
540                non_zero_dealloc(self.memory, self.layout);
541                self.memory = std::ptr::null_mut();
542            }
543        }
544    }
545}
546
547impl DynamicManaged {
548    pub fn new<T: Finalize>(data: T) -> Result<Self, T> {
549        let layout = Layout::new::<T>().pad_to_align();
550        unsafe {
551            let memory = non_zero_alloc(layout);
552            if memory.is_null() {
553                Err(data)
554            } else {
555                memory.cast::<T>().write(data);
556                Ok(Self {
557                    type_hash: TypeHash::of::<T>(),
558                    lifetime: Default::default(),
559                    memory,
560                    layout,
561                    finalizer: T::finalize_raw,
562                    drop: true,
563                })
564            }
565        }
566    }
567
568    pub fn new_raw(
569        type_hash: TypeHash,
570        lifetime: Lifetime,
571        memory: *mut u8,
572        layout: Layout,
573        finalizer: unsafe fn(*mut ()),
574    ) -> Option<Self> {
575        if memory.is_null() {
576            None
577        } else {
578            Some(Self {
579                type_hash,
580                lifetime,
581                memory,
582                layout,
583                finalizer,
584                drop: true,
585            })
586        }
587    }
588
589    pub fn new_uninitialized(
590        type_hash: TypeHash,
591        layout: Layout,
592        finalizer: unsafe fn(*mut ()),
593    ) -> Self {
594        let layout = layout.pad_to_align();
595        let memory = unsafe { non_zero_alloc(layout) };
596        Self {
597            type_hash,
598            lifetime: Default::default(),
599            memory,
600            layout,
601            finalizer,
602            drop: true,
603        }
604    }
605
606    /// # Safety
607    pub unsafe fn from_bytes(
608        type_hash: TypeHash,
609        lifetime: Lifetime,
610        bytes: Vec<u8>,
611        layout: Layout,
612        finalizer: unsafe fn(*mut ()),
613    ) -> Self {
614        let layout = layout.pad_to_align();
615        let memory = unsafe { non_zero_alloc(layout) };
616        unsafe { memory.copy_from(bytes.as_ptr(), bytes.len()) };
617        Self {
618            type_hash,
619            lifetime,
620            memory,
621            layout,
622            finalizer,
623            drop: true,
624        }
625    }
626
627    #[allow(clippy::type_complexity)]
628    pub fn into_inner(mut self) -> (TypeHash, Lifetime, *mut u8, Layout, unsafe fn(*mut ())) {
629        self.drop = false;
630        (
631            self.type_hash,
632            std::mem::take(&mut self.lifetime),
633            self.memory,
634            self.layout,
635            self.finalizer,
636        )
637    }
638
639    pub fn into_typed<T>(self) -> Result<Managed<T>, Self> {
640        Ok(Managed::new(self.consume()?))
641    }
642
643    pub fn renew(mut self) -> Self {
644        self.lifetime = Lifetime::default();
645        self
646    }
647
648    pub fn type_hash(&self) -> &TypeHash {
649        &self.type_hash
650    }
651
652    pub fn lifetime(&self) -> &Lifetime {
653        &self.lifetime
654    }
655
656    pub fn layout(&self) -> &Layout {
657        &self.layout
658    }
659
660    pub fn finalizer(&self) -> unsafe fn(*mut ()) {
661        self.finalizer
662    }
663
664    /// # Safety
665    pub unsafe fn memory(&self) -> &[u8] {
666        unsafe { std::slice::from_raw_parts(self.memory, self.layout.size()) }
667    }
668
669    /// # Safety
670    pub unsafe fn memory_mut(&mut self) -> &mut [u8] {
671        unsafe { std::slice::from_raw_parts_mut(self.memory, self.layout.size()) }
672    }
673
674    pub fn is<T>(&self) -> bool {
675        self.type_hash == TypeHash::of::<T>()
676    }
677
678    pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
679        if self.type_hash == TypeHash::of::<T>() {
680            unsafe { self.lifetime.read_ptr(self.memory.cast::<T>()) }
681        } else {
682            None
683        }
684    }
685
686    pub fn write<T>(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
687        if self.type_hash == TypeHash::of::<T>() {
688            unsafe { self.lifetime.write_ptr(self.memory.cast::<T>()) }
689        } else {
690            None
691        }
692    }
693
694    pub fn consume<T>(mut self) -> Result<T, Self> {
695        if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
696            if self.memory.is_null() {
697                return Err(self);
698            }
699            self.drop = false;
700            let mut result = MaybeUninit::<T>::uninit();
701            unsafe {
702                result.as_mut_ptr().copy_from(self.memory.cast::<T>(), 1);
703                non_zero_dealloc(self.memory, self.layout);
704                self.memory = std::ptr::null_mut();
705                Ok(result.assume_init())
706            }
707        } else {
708            Err(self)
709        }
710    }
711
712    pub fn move_into_ref(self, target: DynamicManagedRefMut) -> Result<(), Self> {
713        if self.type_hash == target.type_hash && self.memory != target.data {
714            if self.memory.is_null() {
715                return Err(self);
716            }
717            let (_, _, memory, layout, _) = self.into_inner();
718            unsafe {
719                target.data.copy_from(memory, layout.size());
720                non_zero_dealloc(memory, layout);
721            }
722            Ok(())
723        } else {
724            Err(self)
725        }
726    }
727
728    pub fn move_into_lazy(self, target: DynamicManagedLazy) -> Result<(), Self> {
729        if self.type_hash == target.type_hash && self.memory != target.data {
730            if self.memory.is_null() {
731                return Err(self);
732            }
733            let (_, _, memory, layout, _) = self.into_inner();
734            unsafe {
735                target.data.copy_from(memory, layout.size());
736                non_zero_dealloc(memory, layout);
737            }
738            Ok(())
739        } else {
740            Err(self)
741        }
742    }
743
744    pub fn borrow(&self) -> Option<DynamicManagedRef> {
745        unsafe { DynamicManagedRef::new_raw(self.type_hash, self.lifetime.borrow()?, self.memory) }
746    }
747
748    pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
749        unsafe {
750            DynamicManagedRefMut::new_raw(self.type_hash, self.lifetime.borrow_mut()?, self.memory)
751        }
752    }
753
754    pub fn lazy(&self) -> DynamicManagedLazy {
755        unsafe {
756            DynamicManagedLazy::new_raw(self.type_hash, self.lifetime.lazy(), self.memory).unwrap()
757        }
758    }
759
760    /// # Safety
761    pub unsafe fn map<T, U: Finalize>(self, f: impl FnOnce(T) -> U) -> Option<Self> {
762        let data = self.consume::<T>().ok()?;
763        let data = f(data);
764        Self::new(data).ok()
765    }
766
767    /// # Safety
768    pub unsafe fn try_map<T, U: Finalize>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Self> {
769        let data = self.consume::<T>().ok()?;
770        let data = f(data)?;
771        Self::new(data).ok()
772    }
773
774    /// # Safety
775    pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
776        if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
777            Some(self.memory.cast::<T>())
778        } else {
779            None
780        }
781    }
782
783    /// # Safety
784    pub unsafe fn as_mut_ptr<T>(&mut self) -> Option<*mut T> {
785        if self.type_hash == TypeHash::of::<T>() && !self.lifetime.state().is_in_use() {
786            Some(self.memory.cast::<T>())
787        } else {
788            None
789        }
790    }
791
792    /// # Safety
793    pub unsafe fn as_ptr_raw(&self) -> *const u8 {
794        self.memory
795    }
796
797    /// # Safety
798    pub unsafe fn as_mut_ptr_raw(&mut self) -> *mut u8 {
799        self.memory
800    }
801}
802
803impl TryFrom<DynamicManagedValue> for DynamicManaged {
804    type Error = ();
805
806    fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
807        match value {
808            DynamicManagedValue::Owned(value) => Ok(value),
809            _ => Err(()),
810        }
811    }
812}
813
814pub struct DynamicManagedRef {
815    type_hash: TypeHash,
816    lifetime: LifetimeRef,
817    data: *const u8,
818}
819
820unsafe impl Send for DynamicManagedRef {}
821unsafe impl Sync for DynamicManagedRef {}
822
823impl DynamicManagedRef {
824    pub fn new<T: ?Sized>(data: &T, lifetime: LifetimeRef) -> Self {
825        Self {
826            type_hash: TypeHash::of::<T>(),
827            lifetime,
828            data: data as *const T as *const u8,
829        }
830    }
831
832    /// # Safety
833    pub unsafe fn new_raw(
834        type_hash: TypeHash,
835        lifetime: LifetimeRef,
836        data: *const u8,
837    ) -> Option<Self> {
838        if data.is_null() {
839            None
840        } else {
841            Some(Self {
842                type_hash,
843                lifetime,
844                data,
845            })
846        }
847    }
848
849    pub fn make<T: ?Sized>(data: &T) -> (Self, Lifetime) {
850        let result = Lifetime::default();
851        (Self::new(data, result.borrow().unwrap()), result)
852    }
853
854    pub fn into_inner(self) -> (TypeHash, LifetimeRef, *const u8) {
855        (self.type_hash, self.lifetime, self.data)
856    }
857
858    pub fn into_typed<T>(self) -> Result<ManagedRef<T>, Self> {
859        if self.type_hash == TypeHash::of::<T>() {
860            unsafe { Ok(ManagedRef::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
861        } else {
862            Err(self)
863        }
864    }
865
866    pub fn type_hash(&self) -> &TypeHash {
867        &self.type_hash
868    }
869
870    pub fn lifetime(&self) -> &LifetimeRef {
871        &self.lifetime
872    }
873
874    pub fn borrow(&self) -> Option<DynamicManagedRef> {
875        Some(DynamicManagedRef {
876            type_hash: self.type_hash,
877            lifetime: self.lifetime.borrow()?,
878            data: self.data,
879        })
880    }
881
882    /// # Safety
883    pub unsafe fn lazy_immutable(&self) -> DynamicManagedLazy {
884        DynamicManagedLazy {
885            type_hash: self.type_hash,
886            lifetime: self.lifetime.lazy(),
887            data: self.data as *mut u8,
888        }
889    }
890
891    pub fn is<T>(&self) -> bool {
892        self.type_hash == TypeHash::of::<T>()
893    }
894
895    pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
896        if self.type_hash == TypeHash::of::<T>() {
897            unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
898        } else {
899            None
900        }
901    }
902
903    /// # Safety
904    pub unsafe fn map<T, U>(self, f: impl FnOnce(&T) -> &U) -> Option<Self> {
905        if self.type_hash == TypeHash::of::<T>() {
906            unsafe {
907                let data = f(&*self.data.cast::<T>());
908                Some(Self {
909                    type_hash: TypeHash::of::<U>(),
910                    lifetime: self.lifetime,
911                    data: data as *const U as *const u8,
912                })
913            }
914        } else {
915            None
916        }
917    }
918
919    /// # Safety
920    pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&T) -> Option<&U>) -> Option<Self> {
921        if self.type_hash == TypeHash::of::<T>() {
922            unsafe {
923                let data = f(&*self.data.cast::<T>())?;
924                Some(Self {
925                    type_hash: TypeHash::of::<U>(),
926                    lifetime: self.lifetime,
927                    data: data as *const U as *const u8,
928                })
929            }
930        } else {
931            None
932        }
933    }
934
935    /// # Safety
936    pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
937        if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
938            Some(self.data.cast::<T>())
939        } else {
940            None
941        }
942    }
943
944    /// # Safety
945    pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
946        if self.lifetime.exists() {
947            Some(self.data)
948        } else {
949            None
950        }
951    }
952}
953
954impl TryFrom<DynamicManagedValue> for DynamicManagedRef {
955    type Error = ();
956
957    fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
958        match value {
959            DynamicManagedValue::Ref(value) => Ok(value),
960            _ => Err(()),
961        }
962    }
963}
964
965pub struct DynamicManagedRefMut {
966    type_hash: TypeHash,
967    lifetime: LifetimeRefMut,
968    data: *mut u8,
969}
970
971unsafe impl Send for DynamicManagedRefMut {}
972unsafe impl Sync for DynamicManagedRefMut {}
973
974impl DynamicManagedRefMut {
975    pub fn new<T: ?Sized>(data: &mut T, lifetime: LifetimeRefMut) -> Self {
976        Self {
977            type_hash: TypeHash::of::<T>(),
978            lifetime,
979            data: data as *mut T as *mut u8,
980        }
981    }
982
983    /// # Safety
984    pub unsafe fn new_raw(
985        type_hash: TypeHash,
986        lifetime: LifetimeRefMut,
987        data: *mut u8,
988    ) -> Option<Self> {
989        if data.is_null() {
990            None
991        } else {
992            Some(Self {
993                type_hash,
994                lifetime,
995                data,
996            })
997        }
998    }
999
1000    pub fn make<T: ?Sized>(data: &mut T) -> (Self, Lifetime) {
1001        let result = Lifetime::default();
1002        (Self::new(data, result.borrow_mut().unwrap()), result)
1003    }
1004
1005    pub fn into_inner(self) -> (TypeHash, LifetimeRefMut, *mut u8) {
1006        (self.type_hash, self.lifetime, self.data)
1007    }
1008
1009    pub fn into_typed<T>(self) -> Result<ManagedRefMut<T>, Self> {
1010        if self.type_hash == TypeHash::of::<T>() {
1011            unsafe { Ok(ManagedRefMut::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1012        } else {
1013            Err(self)
1014        }
1015    }
1016
1017    pub fn type_hash(&self) -> &TypeHash {
1018        &self.type_hash
1019    }
1020
1021    pub fn lifetime(&self) -> &LifetimeRefMut {
1022        &self.lifetime
1023    }
1024
1025    pub fn borrow(&self) -> Option<DynamicManagedRef> {
1026        Some(DynamicManagedRef {
1027            type_hash: self.type_hash,
1028            lifetime: self.lifetime.borrow()?,
1029            data: self.data,
1030        })
1031    }
1032
1033    pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1034        Some(DynamicManagedRefMut {
1035            type_hash: self.type_hash,
1036            lifetime: self.lifetime.borrow_mut()?,
1037            data: self.data,
1038        })
1039    }
1040
1041    pub fn lazy(&self) -> DynamicManagedLazy {
1042        DynamicManagedLazy {
1043            type_hash: self.type_hash,
1044            lifetime: self.lifetime.lazy(),
1045            data: self.data,
1046        }
1047    }
1048
1049    pub fn is<T>(&self) -> bool {
1050        self.type_hash == TypeHash::of::<T>()
1051    }
1052
1053    pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
1054        if self.type_hash == TypeHash::of::<T>() {
1055            unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1056        } else {
1057            None
1058        }
1059    }
1060
1061    pub fn write<T>(&'_ mut self) -> Option<ValueWriteAccess<'_, T>> {
1062        if self.type_hash == TypeHash::of::<T>() {
1063            unsafe { self.lifetime.write_ptr(self.data.cast::<T>()) }
1064        } else {
1065            None
1066        }
1067    }
1068
1069    /// # Safety
1070    pub unsafe fn map<T, U>(self, f: impl FnOnce(&mut T) -> &mut U) -> Option<Self> {
1071        if self.type_hash == TypeHash::of::<T>() {
1072            unsafe {
1073                let data = f(&mut *self.data.cast::<T>());
1074                Some(Self {
1075                    type_hash: TypeHash::of::<U>(),
1076                    lifetime: self.lifetime,
1077                    data: data as *mut U as *mut u8,
1078                })
1079            }
1080        } else {
1081            None
1082        }
1083    }
1084
1085    /// # Safety
1086    pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&mut T) -> Option<&mut U>) -> Option<Self> {
1087        if self.type_hash == TypeHash::of::<T>() {
1088            unsafe {
1089                let data = f(&mut *self.data.cast::<T>())?;
1090                Some(Self {
1091                    type_hash: TypeHash::of::<U>(),
1092                    lifetime: self.lifetime,
1093                    data: data as *mut U as *mut u8,
1094                })
1095            }
1096        } else {
1097            None
1098        }
1099    }
1100
1101    /// # Safety
1102    pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1103        if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1104            Some(self.data.cast::<T>())
1105        } else {
1106            None
1107        }
1108    }
1109
1110    /// # Safety
1111    pub unsafe fn as_mut_ptr<T>(&mut self) -> Option<*mut T> {
1112        if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1113            Some(self.data.cast::<T>())
1114        } else {
1115            None
1116        }
1117    }
1118
1119    /// # Safety
1120    pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1121        if self.lifetime.exists() {
1122            Some(self.data)
1123        } else {
1124            None
1125        }
1126    }
1127
1128    /// # Safety
1129    pub unsafe fn as_mut_ptr_raw(&mut self) -> Option<*mut u8> {
1130        if self.lifetime.exists() {
1131            Some(self.data)
1132        } else {
1133            None
1134        }
1135    }
1136}
1137
1138impl TryFrom<DynamicManagedValue> for DynamicManagedRefMut {
1139    type Error = ();
1140
1141    fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1142        match value {
1143            DynamicManagedValue::RefMut(value) => Ok(value),
1144            _ => Err(()),
1145        }
1146    }
1147}
1148
1149pub struct DynamicManagedLazy {
1150    type_hash: TypeHash,
1151    lifetime: LifetimeLazy,
1152    data: *mut u8,
1153}
1154
1155unsafe impl Send for DynamicManagedLazy {}
1156unsafe impl Sync for DynamicManagedLazy {}
1157
1158impl Clone for DynamicManagedLazy {
1159    fn clone(&self) -> Self {
1160        Self {
1161            type_hash: self.type_hash,
1162            lifetime: self.lifetime.clone(),
1163            data: self.data,
1164        }
1165    }
1166}
1167
1168impl DynamicManagedLazy {
1169    pub fn new<T: ?Sized>(data: &mut T, lifetime: LifetimeLazy) -> Self {
1170        Self {
1171            type_hash: TypeHash::of::<T>(),
1172            lifetime,
1173            data: data as *mut T as *mut u8,
1174        }
1175    }
1176
1177    /// # Safety
1178    pub unsafe fn new_raw(
1179        type_hash: TypeHash,
1180        lifetime: LifetimeLazy,
1181        data: *mut u8,
1182    ) -> Option<Self> {
1183        if data.is_null() {
1184            None
1185        } else {
1186            Some(Self {
1187                type_hash,
1188                lifetime,
1189                data,
1190            })
1191        }
1192    }
1193
1194    pub fn make<T: ?Sized>(data: &mut T) -> (Self, Lifetime) {
1195        let result = Lifetime::default();
1196        (Self::new(data, result.lazy()), result)
1197    }
1198
1199    pub fn into_inner(self) -> (TypeHash, LifetimeLazy, *mut u8) {
1200        (self.type_hash, self.lifetime, self.data)
1201    }
1202
1203    pub fn into_typed<T>(self) -> Result<ManagedLazy<T>, Self> {
1204        if self.type_hash == TypeHash::of::<T>() {
1205            unsafe { Ok(ManagedLazy::new_raw(self.data.cast::<T>(), self.lifetime).unwrap()) }
1206        } else {
1207            Err(self)
1208        }
1209    }
1210
1211    pub fn type_hash(&self) -> &TypeHash {
1212        &self.type_hash
1213    }
1214
1215    pub fn lifetime(&self) -> &LifetimeLazy {
1216        &self.lifetime
1217    }
1218
1219    pub fn is<T>(&self) -> bool {
1220        self.type_hash == TypeHash::of::<T>()
1221    }
1222
1223    pub fn read<T>(&'_ self) -> Option<ValueReadAccess<'_, T>> {
1224        if self.type_hash == TypeHash::of::<T>() {
1225            unsafe { self.lifetime.read_ptr(self.data.cast::<T>()) }
1226        } else {
1227            None
1228        }
1229    }
1230
1231    pub fn write<T>(&'_ self) -> Option<ValueWriteAccess<'_, T>> {
1232        if self.type_hash == TypeHash::of::<T>() {
1233            unsafe { self.lifetime.write_ptr(self.data.cast::<T>()) }
1234        } else {
1235            None
1236        }
1237    }
1238
1239    pub fn borrow(&self) -> Option<DynamicManagedRef> {
1240        Some(DynamicManagedRef {
1241            type_hash: self.type_hash,
1242            lifetime: self.lifetime.borrow()?,
1243            data: self.data,
1244        })
1245    }
1246
1247    pub fn borrow_mut(&mut self) -> Option<DynamicManagedRefMut> {
1248        Some(DynamicManagedRefMut {
1249            type_hash: self.type_hash,
1250            lifetime: self.lifetime.borrow_mut()?,
1251            data: self.data,
1252        })
1253    }
1254
1255    /// # Safety
1256    pub unsafe fn map<T, U>(self, f: impl FnOnce(&mut T) -> &mut U) -> Option<Self> {
1257        if self.type_hash == TypeHash::of::<T>() {
1258            unsafe {
1259                let data = f(&mut *self.data.cast::<T>());
1260                Some(Self {
1261                    type_hash: TypeHash::of::<U>(),
1262                    lifetime: self.lifetime,
1263                    data: data as *mut U as *mut u8,
1264                })
1265            }
1266        } else {
1267            None
1268        }
1269    }
1270
1271    /// # Safety
1272    pub unsafe fn try_map<T, U>(self, f: impl FnOnce(&mut T) -> Option<&mut U>) -> Option<Self> {
1273        if self.type_hash == TypeHash::of::<T>() {
1274            unsafe {
1275                let data = f(&mut *self.data.cast::<T>())?;
1276                Some(Self {
1277                    type_hash: TypeHash::of::<U>(),
1278                    lifetime: self.lifetime,
1279                    data: data as *mut U as *mut u8,
1280                })
1281            }
1282        } else {
1283            None
1284        }
1285    }
1286
1287    /// # Safety
1288    pub unsafe fn as_ptr<T>(&self) -> Option<*const T> {
1289        if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1290            Some(self.data.cast::<T>())
1291        } else {
1292            None
1293        }
1294    }
1295
1296    /// # Safety
1297    pub unsafe fn as_mut_ptr<T>(&self) -> Option<*mut T> {
1298        if self.type_hash == TypeHash::of::<T>() && self.lifetime.exists() {
1299            Some(self.data.cast::<T>())
1300        } else {
1301            None
1302        }
1303    }
1304
1305    /// # Safety
1306    pub unsafe fn as_ptr_raw(&self) -> Option<*const u8> {
1307        if self.lifetime.exists() {
1308            Some(self.data)
1309        } else {
1310            None
1311        }
1312    }
1313
1314    /// # Safety
1315    pub unsafe fn as_mut_ptr_raw(&mut self) -> Option<*mut u8> {
1316        if self.lifetime.exists() {
1317            Some(self.data)
1318        } else {
1319            None
1320        }
1321    }
1322}
1323
1324impl TryFrom<DynamicManagedValue> for DynamicManagedLazy {
1325    type Error = ();
1326
1327    fn try_from(value: DynamicManagedValue) -> Result<Self, Self::Error> {
1328        match value {
1329            DynamicManagedValue::Lazy(value) => Ok(value),
1330            _ => Err(()),
1331        }
1332    }
1333}
1334
1335#[cfg(test)]
1336mod tests {
1337    use super::*;
1338    use std::any::Any;
1339
1340    fn is_async<T: Send + Sync + ?Sized>() {}
1341
1342    #[test]
1343    fn test_managed() {
1344        is_async::<Managed<()>>();
1345        is_async::<ManagedRef<()>>();
1346        is_async::<ManagedRefMut<()>>();
1347        is_async::<ManagedLazy<()>>();
1348        is_async::<ManagedValue<()>>();
1349
1350        let mut value = Managed::new(42);
1351        let mut value_ref = value.borrow_mut().unwrap();
1352        assert!(value_ref.write().is_some());
1353        let mut value_ref2 = value_ref.borrow_mut().unwrap();
1354        assert!(value_ref.write().is_some());
1355        assert!(value_ref2.write().is_some());
1356        drop(value_ref);
1357        let value_ref = value.borrow().unwrap();
1358        assert!(value.borrow().is_some());
1359        assert!(value.borrow_mut().is_none());
1360        drop(value_ref);
1361        assert!(value.borrow().is_some());
1362        assert!(value.borrow_mut().is_some());
1363        *value.write().unwrap() = 40;
1364        assert_eq!(*value.read().unwrap(), 40);
1365        *value.borrow_mut().unwrap().write().unwrap() = 2;
1366        assert_eq!(*value.read().unwrap(), 2);
1367        let value_ref = value.borrow().unwrap();
1368        let value_ref2 = value_ref.borrow().unwrap();
1369        drop(value_ref);
1370        assert!(value_ref2.read().is_some());
1371        let value_ref = value.borrow().unwrap();
1372        let value_lazy = value.lazy();
1373        assert_eq!(*value_lazy.read().unwrap(), 2);
1374        *value_lazy.write().unwrap() = 42;
1375        assert_eq!(*value_lazy.read().unwrap(), 42);
1376        drop(value);
1377        assert!(value_ref.read().is_none());
1378        assert!(value_ref2.read().is_none());
1379        assert!(value_lazy.read().is_none());
1380    }
1381
1382    #[test]
1383    fn test_dynamic_managed() {
1384        is_async::<DynamicManaged>();
1385        is_async::<DynamicManagedRef>();
1386        is_async::<DynamicManagedRefMut>();
1387        is_async::<DynamicManagedLazy>();
1388        is_async::<DynamicManagedValue>();
1389
1390        let mut value = DynamicManaged::new(42).unwrap();
1391        let mut value_ref = value.borrow_mut().unwrap();
1392        assert!(value_ref.write::<i32>().is_some());
1393        let mut value_ref2 = value_ref.borrow_mut().unwrap();
1394        assert!(value_ref.write::<i32>().is_some());
1395        assert!(value_ref2.write::<i32>().is_some());
1396        drop(value_ref);
1397        let value_ref = value.borrow().unwrap();
1398        assert!(value.borrow().is_some());
1399        assert!(value.borrow_mut().is_none());
1400        drop(value_ref);
1401        assert!(value.borrow().is_some());
1402        assert!(value.borrow_mut().is_some());
1403        *value.write::<i32>().unwrap() = 40;
1404        assert_eq!(*value.read::<i32>().unwrap(), 40);
1405        *value.borrow_mut().unwrap().write::<i32>().unwrap() = 2;
1406        assert_eq!(*value.read::<i32>().unwrap(), 2);
1407        let value_ref = value.borrow().unwrap();
1408        let value_ref2 = value_ref.borrow().unwrap();
1409        drop(value_ref);
1410        assert!(value_ref2.read::<i32>().is_some());
1411        let value_ref = value.borrow().unwrap();
1412        let value_lazy = value.lazy();
1413        assert_eq!(*value_lazy.read::<i32>().unwrap(), 2);
1414        *value_lazy.write::<i32>().unwrap() = 42;
1415        assert_eq!(*value_lazy.read::<i32>().unwrap(), 42);
1416        drop(value);
1417        assert!(value_ref.read::<i32>().is_none());
1418        assert!(value_ref2.read::<i32>().is_none());
1419        assert!(value_lazy.read::<i32>().is_none());
1420        let value = DynamicManaged::new("hello".to_owned()).unwrap();
1421        let value = value.consume::<String>().ok().unwrap();
1422        assert_eq!(value.as_str(), "hello");
1423    }
1424
1425    #[test]
1426    fn test_conversion() {
1427        let value = Managed::new(42);
1428        assert_eq!(*value.read().unwrap(), 42);
1429        let value = value.into_dynamic().ok().unwrap();
1430        assert_eq!(*value.read::<i32>().unwrap(), 42);
1431        let mut value = value.into_typed::<i32>().ok().unwrap();
1432        assert_eq!(*value.read().unwrap(), 42);
1433
1434        let value_ref = value.borrow().unwrap();
1435        assert_eq!(*value.read().unwrap(), 42);
1436        let value_ref = value_ref.into_dynamic();
1437        assert_eq!(*value_ref.read::<i32>().unwrap(), 42);
1438        let value_ref = value_ref.into_typed::<i32>().ok().unwrap();
1439        assert_eq!(*value_ref.read().unwrap(), 42);
1440        drop(value_ref);
1441
1442        let value_ref_mut = value.borrow_mut().unwrap();
1443        assert_eq!(*value.read().unwrap(), 42);
1444        let value_ref_mut = value_ref_mut.into_dynamic();
1445        assert_eq!(*value_ref_mut.read::<i32>().unwrap(), 42);
1446        let value_ref_mut = value_ref_mut.into_typed::<i32>().ok().unwrap();
1447        assert_eq!(*value_ref_mut.read().unwrap(), 42);
1448
1449        let value_lazy = value.lazy();
1450        assert_eq!(*value.read().unwrap(), 42);
1451        let value_lazy = value_lazy.into_dynamic();
1452        assert_eq!(*value_lazy.read::<i32>().unwrap(), 42);
1453        let value_lazy = value_lazy.into_typed::<i32>().ok().unwrap();
1454        assert_eq!(*value_lazy.read().unwrap(), 42);
1455    }
1456
1457    #[test]
1458    fn test_unsized() {
1459        let lifetime = Lifetime::default();
1460        let mut data = 42usize;
1461        {
1462            let foo = ManagedRef::<dyn Any>::new(&data, lifetime.borrow().unwrap());
1463            assert_eq!(
1464                *foo.read().unwrap().downcast_ref::<usize>().unwrap(),
1465                42usize
1466            );
1467        }
1468        {
1469            let mut foo = ManagedRefMut::<dyn Any>::new(&mut data, lifetime.borrow_mut().unwrap());
1470            *foo.write().unwrap().downcast_mut::<usize>().unwrap() = 100;
1471        }
1472        {
1473            let foo = ManagedLazy::<dyn Any>::new(&mut data, lifetime.lazy());
1474            assert_eq!(
1475                *foo.read().unwrap().downcast_ref::<usize>().unwrap(),
1476                100usize
1477            );
1478        }
1479
1480        let lifetime = Lifetime::default();
1481        let mut data = [0, 1, 2, 3];
1482        {
1483            let foo = ManagedRef::<[i32]>::new(&data, lifetime.borrow().unwrap());
1484            assert_eq!(*foo.read().unwrap(), [0, 1, 2, 3]);
1485        }
1486        {
1487            let mut foo = ManagedRefMut::<[i32]>::new(&mut data, lifetime.borrow_mut().unwrap());
1488            foo.write().unwrap().sort_by(|a, b| a.cmp(b).reverse());
1489        }
1490        {
1491            let foo = ManagedLazy::<[i32]>::new(&mut data, lifetime.lazy());
1492            assert_eq!(*foo.read().unwrap(), [3, 2, 1, 0]);
1493        }
1494    }
1495
1496    #[test]
1497    fn test_moves() {
1498        let mut value = Managed::new(42);
1499        assert_eq!(*value.read().unwrap(), 42);
1500        {
1501            let value_ref = value.borrow_mut().unwrap();
1502            Managed::new(1).move_into_ref(value_ref).ok().unwrap();
1503            assert_eq!(*value.read().unwrap(), 1);
1504        }
1505        {
1506            let value_lazy = value.lazy();
1507            Managed::new(2).move_into_lazy(value_lazy).ok().unwrap();
1508            assert_eq!(*value.read().unwrap(), 2);
1509        }
1510
1511        let mut value = DynamicManaged::new(42).unwrap();
1512        assert_eq!(*value.read::<i32>().unwrap(), 42);
1513        {
1514            let value_ref = value.borrow_mut().unwrap();
1515            DynamicManaged::new(1)
1516                .unwrap()
1517                .move_into_ref(value_ref)
1518                .ok()
1519                .unwrap();
1520            assert_eq!(*value.read::<i32>().unwrap(), 1);
1521        }
1522        {
1523            let value_lazy = value.lazy();
1524            DynamicManaged::new(2)
1525                .unwrap()
1526                .move_into_lazy(value_lazy)
1527                .ok()
1528                .unwrap();
1529            assert_eq!(*value.read::<i32>().unwrap(), 2);
1530        }
1531    }
1532
1533    #[test]
1534    fn test_move_invalidation() {
1535        let value = Managed::new(42);
1536        let value_ref = value.borrow().unwrap();
1537        assert_eq!(value.lifetime().tag(), value_ref.lifetime().tag());
1538        assert!(value_ref.lifetime().exists());
1539        let value = Box::new(value);
1540        assert_ne!(value.lifetime().tag(), value_ref.lifetime().tag());
1541        assert!(!value_ref.lifetime().exists());
1542        let value = *value;
1543        assert_ne!(value.lifetime().tag(), value_ref.lifetime().tag());
1544        assert!(!value_ref.lifetime().exists());
1545    }
1546}