any_vec/ops/
temp.rs

1use core::any::TypeId;
2use core::{mem, ptr};
3use crate::any_value::{AnyValue, AnyValueCloneable, AnyValueMut, AnyValueSizeless, AnyValueSizelessMut, AnyValueTypeless, AnyValueTypelessMut, Unknown};
4use crate::any_vec_raw::AnyVecRaw;
5use crate::any_vec_ptr::{IAnyVecPtr, IAnyVecRawPtr};
6use crate::{AnyVec, copy_nonoverlapping_value};
7use crate::traits::Cloneable;
8
9pub trait Operation {
10    type AnyVecPtr: IAnyVecRawPtr;
11
12    fn any_vec_ptr(&self) -> Self::AnyVecPtr;
13
14    fn bytes(&self) -> *const u8;
15
16    /// Called after bytes move.
17    fn consume(&mut self);
18}
19
20/// Temporary existing value in memory.
21/// Data will be erased with TempValue destruction.
22///
23/// Have internal `&mut AnyVec`.
24///
25/// May do some postponed actions on consumption/destruction.
26///
27pub struct TempValue<Op: Operation>{
28    op: Op,
29}
30impl<Op: Operation> TempValue<Op>{
31    #[inline]
32    pub(crate) fn new(op: Op) -> Self {
33        Self{op}
34    }
35
36    #[inline]
37    fn any_vec_raw(&self) -> &AnyVecRaw<<Op::AnyVecPtr as IAnyVecRawPtr>::M>{
38        unsafe{ self.op.any_vec_ptr().any_vec_raw() }
39    }
40
41    #[inline]
42    fn bytes_len(&self) -> usize{
43        if Unknown::is::<<Op::AnyVecPtr as IAnyVecRawPtr>::Element>() {
44            self.any_vec_raw().element_layout().size()
45        } else{
46            mem::size_of::<<Op::AnyVecPtr as IAnyVecRawPtr>::Element>()
47        }
48    }
49}
50
51impl<Op: Operation> AnyValueSizeless for TempValue<Op> {
52    type Type = <Op::AnyVecPtr as IAnyVecRawPtr>::Element;
53
54    #[inline]
55    fn as_bytes_ptr(&self) -> *const u8 {
56        self.op.bytes()
57    }
58
59    #[inline]
60    unsafe fn move_into<KnownType:'static /*= Unknown*/>(mut self, out: *mut u8, bytes_size: usize) {
61        copy_nonoverlapping_value::<KnownType>(self.as_bytes_ptr(), out, bytes_size);
62        self.op.consume();
63        mem::forget(self);
64    }
65}
66impl<Op: Operation> AnyValueSizelessMut for TempValue<Op> {
67    #[inline]
68    fn as_bytes_mut_ptr(&mut self) -> *mut u8 {
69        // Somehow this is OK with MIRI.
70        self.op.bytes() as *mut u8
71    }
72}
73impl<Op: Operation> AnyValueTypeless for TempValue<Op>{
74    #[inline]
75    fn size(&self) -> usize {
76        self.bytes_len()
77    }
78}
79impl<Op: Operation> AnyValue for TempValue<Op>{
80    #[inline]
81    fn value_typeid(&self) -> TypeId {
82        let typeid = TypeId::of::<Self::Type>();
83        if typeid == TypeId::of::<Unknown>(){
84            self.any_vec_raw().type_id
85        } else {
86            typeid
87        }
88    }
89}
90
91impl<Op: Operation> AnyValueTypelessMut for TempValue<Op> {}
92impl<Op: Operation> AnyValueMut for TempValue<Op> {}
93
94impl<Op: Operation> AnyValueCloneable for TempValue<Op>
95where
96    Op::AnyVecPtr: IAnyVecPtr,
97    <Op::AnyVecPtr as IAnyVecPtr>::Traits: Cloneable
98{
99    #[inline]
100    unsafe fn clone_into(&self, out: *mut u8) {
101        let clone_fn = self.op.any_vec_ptr().any_vec().clone_fn();
102        (clone_fn)(self.as_bytes().as_ptr(), out, 1);
103    }
104}
105
106impl<Op: Operation> Drop for TempValue<Op>{
107    #[inline]
108    fn drop(&mut self) {
109        unsafe{
110            let drop_fn = self.any_vec_raw().drop_fn;
111            let element = self.op.bytes() as *mut u8;
112
113            // compile-time check
114            if Unknown::is::<<Self as AnyValueSizeless>::Type>() {
115                if let Some(drop_fn) = drop_fn{
116                    (drop_fn)(element, 1);
117                }
118            } else {
119                ptr::drop_in_place(element as *mut <Self as AnyValueSizeless>::Type);
120            }
121        }
122        self.op.consume();
123    }
124}
125
126unsafe impl<Op: Operation> Send for TempValue<Op>
127where
128    Op::AnyVecPtr: IAnyVecPtr,
129    AnyVec<
130        <Op::AnyVecPtr as IAnyVecPtr>::Traits,
131        <Op::AnyVecPtr as IAnyVecRawPtr>::M
132    >: Send
133{}
134
135unsafe impl<Op: Operation> Sync for TempValue<Op>
136where
137    Op::AnyVecPtr: IAnyVecPtr,
138    AnyVec<
139        <Op::AnyVecPtr as IAnyVecPtr>::Traits,
140        <Op::AnyVecPtr as IAnyVecRawPtr>::M
141    >: Sync
142{}