variadic_arguments/argument/arg/
inner.rs1#[cfg(no_std)]
2use core::{
3 any::Any,
4 fmt::Debug,
5 mem::{ManuallyDrop, MaybeUninit},
6};
7
8use crate::{argument::VariantHandle,argument::discriminant::Discriminant, OwnedArgument};
9
10#[cfg(not(no_std))]
11use std::{
12 any::Any,
13 fmt::Debug,
14 mem::{ManuallyDrop, MaybeUninit}
15};
16
17#[derive(Debug)]
19pub enum ArgumentKind<'a>
20{
21 Borrowed(&'a dyn Any),
23 Owned(OwnedArgument)
25}
26
27pub(super) enum RawArgument<'a>
28{
29 Borrowed(&'a dyn VariantHandle),
30 Owned(OwnedArgument)
31}
32
33pub(super) union InnerArgument<'a>
35{
36 owned: ManuallyDrop<OwnedArgument>,
39 ref_: &'a dyn VariantHandle
42}
43
44impl InnerArgument<'_>
45{
46 #[inline(always)]
48 pub fn new_owned(item: OwnedArgument) -> Self
49 {
50 let owned = ManuallyDrop::new(item);
51
52 Self
53 {
54 owned
55 }
56 }
57
58
59 #[inline(always)]
61 pub fn discriminant(&self) -> Discriminant
62 {
63 unsafe
65 {
66 self.owned
67 .discriminant()
68 }
69 }
70
71
72 #[inline(always)]
73 pub fn is_owned(&self) -> bool
74 {
75 matches!(self.discriminant(), Discriminant::Inlined | Discriminant::Allocated )
76 }
77
78
79 #[inline(always)]
80 pub fn is_borrowed(&self) -> bool
81 {
82 matches!(self.discriminant(), Discriminant::Borrowed)
83 }
84
85
86 #[inline(always)]
87 pub fn to_mut(&mut self) -> &mut dyn Any
88 {
89 match self.discriminant()
90 {
91 Discriminant::Borrowed =>
92 {
93 let owned : OwnedArgument =
94 unsafe
95 {
96 self.ref_.clone_object()
97 };
98
99 *self = InnerArgument::new_owned(owned);
100
101 match self.discriminant()
102 {
103 Discriminant::Inlined | Discriminant::Allocated =>
104 unsafe
105 {
106 &mut *self.owned
107 },
108 _ => unreachable!()
109 }
110 }
111 _ =>
112 unsafe
113 {
114 &mut *self.owned
115 }
116 }
117 }
118
119
120 #[inline(always)]
125 pub unsafe fn owned_debug_handle(&self) -> &dyn Debug
126 {
127 unsafe
128 {
129 &*self.owned
130 }
131 }
132}
133
134
135impl<'a> InnerArgument<'a>
136{
137 #[inline(always)]
139 pub fn new_ref(ref_: &'a dyn VariantHandle) -> Self
140 {
141 let mut output : Self = unsafe { MaybeUninit::zeroed().assume_init() };
143
144 output.ref_ = ref_;
145
146 output
147 }
148
149 #[inline(always)]
151 pub fn as_ref(&'a self) -> Self
152 {
153 let ref_ =
154 match self.discriminant()
155 {
156 Discriminant::Borrowed => unsafe { self.ref_unchecked() },
157 _ => unsafe { self.owned.raw_ref() }
158 };
159
160 Self::new_ref(ref_)
161 }
162
163 #[must_use = "Potential memory leak."]
169 #[inline(always)]
170 pub unsafe fn take_raw_argument(&mut self) -> RawArgument<'a>
171 {
172 match self.discriminant()
173 {
174 Discriminant::Borrowed =>
175 {
176 let ref_ = unsafe { self.ref_unchecked() };
177
178 RawArgument::Borrowed(ref_)
179 }
180 _ =>
181 {
182 let owned =
183 unsafe
184 {
185 ManuallyDrop::take(&mut self.owned)
186 };
187
188 RawArgument::Owned(owned)
189 }
190 }
191 }
192
193
194 #[inline(always)]
195 pub fn into_inner(self) -> ArgumentKind<'a>
196 {
197 match self.discriminant()
198 {
199 Discriminant::Borrowed => ArgumentKind::Borrowed(unsafe { self.ref_unchecked() }),
200 _ => ArgumentKind::Owned(ManuallyDrop::into_inner(unsafe { self.owned }))
201 }
202 }
203
204
205 #[inline(always)]
210 pub unsafe fn ref_unchecked(&self) -> &'a dyn VariantHandle
211 {
212 unsafe
213 {
214 self.ref_
215 }
216 }
217
218
219 #[inline(always)]
220 pub fn to_ref(&'a self) -> &'a dyn Any
221 {
222 match self.discriminant()
223 {
224 Discriminant::Borrowed => unsafe { self.ref_unchecked() },
225 _ => unsafe { self.owned.raw_ref() }
226 }
227 }
228}