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 fn consume(&mut self);
18}
19
20pub 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 >(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 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 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{}