opencv/manual/core/
tuple.rs

1use std::ffi::c_void;
2use std::marker::PhantomData;
3use std::mem::ManuallyDrop;
4
5use crate::traits::Boxed;
6
7/// Wrapper for C++ [std::tupe](https://en.cppreference.com/w/cpp/utility/tuple) and
8/// [std::pair](https://en.cppreference.com/w/cpp/utility/pair)
9pub struct Tuple<T>
10where
11	Self: TupleExtern,
12{
13	ptr: *mut c_void,
14	_d: PhantomData<T>,
15}
16
17impl<T> Boxed for Tuple<T>
18where
19	Self: TupleExtern,
20{
21	#[inline]
22	unsafe fn from_raw(ptr: *mut c_void) -> Self {
23		Self { ptr, _d: PhantomData }
24	}
25
26	#[inline]
27	fn into_raw(self) -> *mut c_void {
28		ManuallyDrop::new(self).ptr
29	}
30
31	#[inline]
32	fn as_raw(&self) -> *const c_void {
33		self.ptr
34	}
35
36	#[inline]
37	fn as_raw_mut(&mut self) -> *mut c_void {
38		self.ptr
39	}
40}
41
42impl<T> Drop for Tuple<T>
43where
44	Tuple<T>: TupleExtern,
45{
46	fn drop(&mut self) {
47		unsafe { self.extern_delete() }
48	}
49}
50
51pub trait TupleExtern {
52	#[doc(hidden)]
53	unsafe fn extern_delete(&mut self);
54}
55
56#[doc(hidden)]
57#[macro_export]
58macro_rules! tuple_extern {
59	(
60		$type: ty,
61		$extern_new: ident, $extern_delete: ident,
62		$($num: tt = $arg: ident: $element_type: ty, $element_get: ident via $extern_element_get: ident),+
63	) => {
64		impl $crate::core::TupleExtern for $crate::core::Tuple<$type> {
65			#[inline]
66			unsafe fn extern_delete(&mut self) {
67				unsafe { $crate::sys::$extern_delete(self.as_raw_mut()) }
68			}
69		}
70
71		impl $crate::core::Tuple<$type> {
72			$(
73			#[inline]
74			pub fn $element_get(&self) -> $element_type {
75				return_send!(via ocvrs_return);
76				unsafe { $crate::sys::$extern_element_get(self.as_raw(), ocvrs_return.as_mut_ptr()); }
77				return_receive!(ocvrs_return => ret);
78				unsafe { <$element_type>::opencv_from_extern(ret) }
79			}
80			)+
81
82			/// Create new from a Rust tuple
83			#[inline]
84			pub fn new(s: $type) -> Self {
85				$( let mut $arg = s.$num.opencv_into_extern_container_nofail(); )+
86				unsafe { Self::opencv_from_extern($crate::sys::$extern_new($( $arg.opencv_as_extern_mut() ),+)) }
87			}
88
89			/// Convert into a Rust tuple
90			#[inline]
91			pub fn into_tuple(self) -> $type {
92				($( self.$element_get() ),+)
93			}
94		}
95	};
96}
97
98unsafe impl<T: Send> Send for Tuple<T> where Self: TupleExtern {}
99
100unsafe impl<T: Sync> Sync for Tuple<T> where Self: TupleExtern {}