opencv/
boxed_ref.rs

1use std::fmt;
2use std::marker::PhantomData;
3
4use crate::mod_prelude::OpenCVTypeExternContainer;
5use crate::traits::{Boxed, OpenCVFromExtern, OpenCVIntoExternContainer, OpenCVType};
6
7/// Wrapper for the type implementing [Boxed] trait that allows to retain the lifetime of the referenced object.
8///
9/// This wrapper implements all traits that the underlying type does, but explicitly doesn't implement [Deref](core::ops::Deref) and
10/// [DerefMut](core::ops::DerefMut) to avoid being able to [swap](core::mem::swap) the reference out of the wrapper. It relies on
11/// functions accepting generic arguments (e.g. `impl MatTrait` or `impl MatTraitConst`) which are implemented by both main struct
12/// and its `BoxedRef` (e.g. [Mat](crate::core::Mat) and `BoxedRef<Mat>`).
13#[repr(transparent)]
14pub struct BoxedRef<'r, T: Boxed> {
15	pub(crate) reference: T,
16	referenced_object: PhantomData<&'r T>,
17}
18
19impl<T: Boxed> From<T> for BoxedRef<'_, T> {
20	#[inline]
21	fn from(value: T) -> Self {
22		Self {
23			reference: value,
24			referenced_object: PhantomData,
25		}
26	}
27}
28
29impl<T: Boxed + fmt::Debug> fmt::Debug for BoxedRef<'_, T> {
30	#[inline]
31	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32		fmt::Debug::fmt(&self.reference, f)
33	}
34}
35
36impl<T: Boxed + Clone> BoxedRef<'_, T> {
37	/// Clones the pointee of this [BoxedRef]
38	#[inline]
39	pub fn clone_pointee(&self) -> T {
40		self.reference.clone()
41	}
42}
43
44impl<T: OpenCVIntoExternContainer + Boxed> OpenCVIntoExternContainer for BoxedRef<'_, T> {
45	type ExternContainer = T::ExternContainer;
46
47	#[inline]
48	fn opencv_into_extern_container_nofail(self) -> Self::ExternContainer {
49		self.reference.opencv_into_extern_container_nofail()
50	}
51}
52
53impl<'t, 'b, T: OpenCVType<'t> + Boxed> OpenCVType<'t> for BoxedRef<'b, T> {
54	type Arg = BoxedRef<'b, T>;
55}
56
57impl<T: OpenCVFromExtern + Boxed> OpenCVFromExtern for BoxedRef<'_, T> {
58	type ExternReceive = T::ExternReceive;
59
60	#[inline]
61	unsafe fn opencv_from_extern(s: Self::ExternReceive) -> Self {
62		Self {
63			reference: unsafe { T::opencv_from_extern(s) },
64			referenced_object: PhantomData,
65		}
66	}
67}
68
69impl<T: Boxed + OpenCVTypeExternContainer> OpenCVTypeExternContainer for BoxedRef<'_, T> {
70	type ExternSend = T::ExternSend;
71	type ExternSendMut = T::ExternSendMut;
72
73	#[inline]
74	fn opencv_as_extern(&self) -> Self::ExternSend {
75		self.reference.opencv_as_extern()
76	}
77
78	#[inline]
79	fn opencv_as_extern_mut(&mut self) -> Self::ExternSendMut {
80		self.reference.opencv_as_extern_mut()
81	}
82}
83
84/// Mutable version of [BoxedRef], implements the traits that take `&mut self`.
85#[repr(transparent)]
86pub struct BoxedRefMut<'r, T: Boxed> {
87	pub(crate) reference: T,
88	referenced_object: PhantomData<&'r mut T>,
89}
90
91impl<T: Boxed> From<T> for BoxedRefMut<'_, T> {
92	#[inline]
93	fn from(value: T) -> Self {
94		Self {
95			reference: value,
96			referenced_object: PhantomData,
97		}
98	}
99}
100
101impl<T: Boxed + fmt::Debug> fmt::Debug for BoxedRefMut<'_, T> {
102	#[inline]
103	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104		fmt::Debug::fmt(&self.reference, f)
105	}
106}
107
108impl<T: Boxed + Clone> BoxedRefMut<'_, T> {
109	/// Clones the pointee of this [BoxedRefMut]
110	#[inline]
111	pub fn clone_pointee(&self) -> T {
112		self.reference.clone()
113	}
114}
115
116impl<'r, T: Boxed> From<BoxedRefMut<'r, T>> for BoxedRef<'r, T> {
117	/// Irreversibly convert this [BoxedRefMut] into a non-mutable [BoxedRef]
118	fn from(value: BoxedRefMut<'r, T>) -> Self {
119		BoxedRef::from(value.reference)
120	}
121}
122
123impl<T: OpenCVIntoExternContainer + Boxed> OpenCVIntoExternContainer for BoxedRefMut<'_, T> {
124	type ExternContainer = T::ExternContainer;
125
126	#[inline]
127	fn opencv_into_extern_container_nofail(self) -> Self::ExternContainer {
128		self.reference.opencv_into_extern_container_nofail()
129	}
130}
131
132impl<'t, 'b, T: OpenCVType<'t> + Boxed> OpenCVType<'t> for BoxedRefMut<'b, T> {
133	type Arg = BoxedRefMut<'b, T>;
134}
135
136impl<T: OpenCVFromExtern + Boxed> OpenCVFromExtern for BoxedRefMut<'_, T> {
137	type ExternReceive = T::ExternReceive;
138
139	#[inline]
140	unsafe fn opencv_from_extern(s: Self::ExternReceive) -> Self {
141		Self {
142			reference: unsafe { T::opencv_from_extern(s) },
143			referenced_object: PhantomData,
144		}
145	}
146}
147
148impl<T: Boxed + OpenCVTypeExternContainer> OpenCVTypeExternContainer for BoxedRefMut<'_, T> {
149	type ExternSend = T::ExternSend;
150	type ExternSendMut = T::ExternSendMut;
151
152	#[inline]
153	fn opencv_as_extern(&self) -> Self::ExternSend {
154		self.reference.opencv_as_extern()
155	}
156
157	#[inline]
158	fn opencv_as_extern_mut(&mut self) -> Self::ExternSendMut {
159		self.reference.opencv_as_extern_mut()
160	}
161}
162
163#[doc(hidden)]
164#[macro_export]
165macro_rules! boxed_ref {
166	($typ: ty, $const_trait: ty, $const_method: ident, $mut_trait: ty, $mut_method: ident) => {
167		impl $const_trait for $crate::boxed_ref::BoxedRef<'_, $typ> {
168			#[inline]
169			fn $const_method(&self) -> extern_send!(Self) {
170				self.reference.$const_method()
171			}
172		}
173
174		impl $const_trait for $crate::boxed_ref::BoxedRefMut<'_, $typ> {
175			#[inline]
176			fn $const_method(&self) -> extern_send!(Self) {
177				self.reference.$const_method()
178			}
179		}
180
181		impl $mut_trait for $crate::boxed_ref::BoxedRefMut<'_, $typ> {
182			#[inline]
183			fn $mut_method(&mut self) -> extern_send!(mut Self) {
184				self.reference.$mut_method()
185			}
186		}
187	};
188}