opencv/manual/core/
vector.rs1use std::borrow::Borrow;
2use std::ffi::c_void;
3use std::iter::FromIterator;
4use std::marker::PhantomData;
5use std::mem::ManuallyDrop;
6use std::{fmt, mem, slice};
7
8pub use iter::{VectorIterator, VectorRefIterator};
9pub use vector_extern::{VectorExtern, VectorExternCopyNonBool};
10
11use crate::boxed_ref::BoxedRef;
12use crate::platform_types::size_t;
13use crate::traits::{Boxed, OpenCVFromExtern, OpenCVIntoExternContainer, OpenCVType, OpenCVTypeExternContainer};
14use crate::Result;
15
16mod iter;
17mod vector_extern;
18
19pub struct Vector<T>
21where
22 Self: VectorExtern<T>,
23{
24 ptr: *mut c_void,
25 _d: PhantomData<T>,
26}
27
28impl<T> Vector<T>
29where
30 Self: VectorExtern<T>,
31{
32 #[inline]
34 pub fn new() -> Self {
35 unsafe { Self::from_raw(Self::extern_new()) }
36 }
37
38 #[inline]
40 pub fn with_capacity(capacity: size_t) -> Self {
41 let mut out = Self::new();
42 out.reserve(capacity);
43 out
44 }
45
46 #[inline]
48 pub fn from_iter<'a>(s: impl IntoIterator<Item = <T as OpenCVType<'a>>::Arg>) -> Self
49 where
50 T: for<'t> OpenCVType<'t>,
51 {
52 #![allow(clippy::should_implement_trait)]
53 let mut out = Self::new();
54 out.extend(s);
55 out
56 }
57
58 #[inline]
60 pub fn from_slice(s: &[T]) -> Self
61 where
62 Self: VectorExternCopyNonBool<T>,
63 {
64 unsafe { Self::from_raw(Self::extern_from_slice(s.as_ptr(), s.len())) }
65 }
66
67 #[inline]
68 pub fn from_elem<'a>(elem: <T as OpenCVType<'a>>::Arg, n: size_t) -> Self
69 where
70 T: for<'t> OpenCVType<'t>,
71 <T as OpenCVType<'a>>::Arg: Clone,
72 {
73 let mut out = Self::with_capacity(n);
74 for _ in 0..n {
75 out.push(elem.clone());
76 }
77 out
78 }
79
80 #[inline]
82 pub fn len(&self) -> size_t {
83 unsafe { self.extern_len() }
84 }
85
86 #[inline]
88 pub fn is_empty(&self) -> bool {
89 unsafe { self.extern_is_empty() }
90 }
91
92 #[inline]
94 pub fn capacity(&self) -> size_t {
95 unsafe { self.extern_capacity() }
96 }
97
98 #[inline]
100 pub fn shrink_to_fit(&mut self) {
101 unsafe { self.extern_shrink_to_fit() }
102 }
103
104 #[inline]
106 pub fn reserve(&mut self, additional: size_t) {
107 unsafe { self.extern_reserve(additional) }
108 }
109
110 #[inline]
112 pub fn clear(&mut self) {
113 unsafe { self.extern_clear() }
114 }
115
116 #[inline]
118 pub fn remove(&mut self, index: size_t) -> Result<()> {
119 vector_index_check(index, self.len())?;
120 unsafe { self.extern_remove(index) }
121 Ok(())
122 }
123
124 #[inline]
126 pub fn swap(&mut self, index1: size_t, index2: size_t) -> Result<()> {
127 let len = self.len();
128 vector_index_check(index1, len)?;
129 vector_index_check(index2, len)?;
130 if index1 != index2 {
131 unsafe { self.extern_swap(index1, index2) }
132 }
133 Ok(())
134 }
135
136 #[inline]
138 pub fn push(&mut self, val: <T as OpenCVType>::Arg)
139 where
140 T: for<'t> OpenCVType<'t>,
141 {
142 let val = val.opencv_into_extern_container_nofail();
143 unsafe { self.extern_push(val.opencv_as_extern()) }
144 }
145
146 #[inline]
147 pub(crate) fn push_owned(&mut self, val: T)
148 where
149 T: OpenCVIntoExternContainer,
150 {
151 let val = val.opencv_into_extern_container_nofail();
152 unsafe { self.extern_push_owned(val.opencv_as_extern()) }
153 }
154
155 #[inline]
157 pub fn insert(&mut self, index: size_t, val: <T as OpenCVType>::Arg) -> Result<()>
158 where
159 T: for<'t> OpenCVType<'t>,
160 {
161 vector_index_check(index, self.len() + 1)?;
162 let val = val.opencv_into_extern_container()?;
163 unsafe { self.extern_insert(index, val.opencv_as_extern()) }
164 Ok(())
165 }
166
167 #[inline]
169 pub fn set(&mut self, index: size_t, val: <T as OpenCVType>::Arg) -> Result<()>
170 where
171 T: for<'t> OpenCVType<'t>,
172 {
173 vector_index_check(index, self.len())?;
174 let val = val.opencv_into_extern_container()?;
175 unsafe { self.extern_set(index, val.opencv_as_extern()) }
176 Ok(())
177 }
178
179 #[inline]
183 pub unsafe fn set_unchecked(&mut self, index: size_t, val: <T as OpenCVType>::Arg)
184 where
185 T: for<'t> OpenCVType<'t>,
186 {
187 let val = val.opencv_into_extern_container_nofail();
188 unsafe { self.extern_set(index, val.opencv_as_extern()) }
189 }
190
191 #[inline]
193 pub fn get(&self, index: size_t) -> Result<T>
194 where
195 T: OpenCVFromExtern,
196 {
197 vector_index_check(index, self.len())?;
198 Ok(unsafe { self.get_unchecked(index) })
199 }
200
201 #[inline]
205 pub unsafe fn get_unchecked(&self, index: size_t) -> T
206 where
207 T: OpenCVFromExtern,
208 {
209 let val = unsafe { self.extern_get(index) };
210 unsafe { T::opencv_from_extern(val) }
211 }
212
213 #[inline]
214 pub fn iter(&self) -> VectorRefIterator<T> {
215 VectorRefIterator::new(self)
216 }
217
218 #[inline]
223 pub fn as_slice(&self) -> &[T]
224 where
225 Self: VectorExternCopyNonBool<T>,
226 {
227 let data = unsafe { self.extern_data() };
228 if data.is_null() {
229 &[]
230 } else {
231 unsafe { slice::from_raw_parts(data, self.len()) }
232 }
233 }
234
235 #[inline]
240 pub fn as_mut_slice(&mut self) -> &mut [T]
241 where
242 Self: VectorExternCopyNonBool<T>,
243 {
244 let data = unsafe { self.extern_data_mut() };
245 if data.is_null() {
246 &mut []
247 } else {
248 unsafe { slice::from_raw_parts_mut(data, self.len()) }
249 }
250 }
251}
252
253pub trait VectorToVec {
254 type Element;
255
256 fn to_vec(&self) -> Vec<Self::Element>;
258}
259
260impl<T> Default for Vector<T>
261where
262 Self: VectorExtern<T>,
263{
264 #[inline]
265 fn default() -> Vector<T> {
266 Vector::new()
267 }
268}
269
270impl<T> From<Vector<T>> for Vec<T>
271where
272 Vector<T>: VectorExtern<T> + VectorToVec<Element = T>,
273{
274 #[inline]
275 fn from(from: Vector<T>) -> Self {
276 from.to_vec()
277 }
278}
279
280impl<T: for<'o> OpenCVType<'o>> From<Vec<<T as OpenCVType<'_>>::Arg>> for Vector<T>
281where
282 Vector<T>: VectorExtern<T>,
283{
284 #[inline]
285 fn from(from: Vec<<T as OpenCVType<'_>>::Arg>) -> Self {
286 Self::from_iter(from)
287 }
288}
289
290impl<'a, T: for<'o> OpenCVType<'o>> FromIterator<<T as OpenCVType<'a>>::Arg> for Vector<T>
291where
292 Self: VectorExtern<T>,
293{
294 #[inline]
295 fn from_iter<I: IntoIterator<Item = <T as OpenCVType<'a>>::Arg>>(s: I) -> Vector<T> {
296 Self::from_iter(s)
297 }
298}
299
300impl<T> AsRef<[T]> for Vector<T>
301where
302 Self: VectorExtern<T> + VectorExternCopyNonBool<T>,
303{
304 #[inline]
305 fn as_ref(&self) -> &[T] {
306 self.as_slice()
307 }
308}
309
310impl<T> Borrow<[T]> for Vector<T>
311where
312 Self: VectorExtern<T> + VectorExternCopyNonBool<T>,
313{
314 #[inline]
315 fn borrow(&self) -> &[T] {
316 self.as_slice()
317 }
318}
319
320impl<T: OpenCVFromExtern + fmt::Debug> fmt::Debug for Vector<T>
321where
322 Self: VectorExtern<T>,
323{
324 #[inline]
325 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
326 f.debug_list().entries(self).finish()
327 }
328}
329
330impl<T> Drop for Vector<T>
331where
332 Self: VectorExtern<T>,
333{
334 fn drop(&mut self) {
335 unsafe { self.extern_delete() }
336 }
337}
338
339unsafe impl<T: Send> Send for Vector<T> where Self: VectorExtern<T> {}
340
341unsafe impl<T: Sync> Sync for Vector<T> where Self: VectorExtern<T> {}
342
343impl<'a, T: for<'o> OpenCVType<'o>> Extend<<T as OpenCVType<'a>>::Arg> for Vector<T>
344where
345 Self: VectorExtern<T>,
346{
347 fn extend<I: IntoIterator<Item = <T as OpenCVType<'a>>::Arg>>(&mut self, s: I) {
348 let s = s.into_iter();
349 let (lo, hi) = s.size_hint();
350 self.reserve(hi.unwrap_or(lo));
351 s.for_each(|elem| {
352 self.push(elem);
353 });
354 }
355}
356
357impl<T> Boxed for Vector<T>
358where
359 Self: VectorExtern<T>,
360{
361 #[inline]
362 unsafe fn from_raw(ptr: *mut c_void) -> Self {
363 Self { ptr, _d: PhantomData }
364 }
365
366 #[inline]
367 fn into_raw(self) -> *mut c_void {
368 ManuallyDrop::new(self).ptr
369 }
370
371 #[inline]
372 fn as_raw(&self) -> *const c_void {
373 self.ptr
374 }
375
376 #[inline]
377 fn as_raw_mut(&mut self) -> *mut c_void {
378 self.ptr
379 }
380}
381
382impl<'b, T: Boxed> Vector<BoxedRef<'b, T>>
383where
384 Self: VectorExtern<BoxedRef<'b, T>>,
385 Vector<T>: VectorExtern<T>,
386{
387 pub(crate) fn as_non_ref_vec(&self) -> &Vector<T> {
390 unsafe { mem::transmute::<_, &Vector<T>>(self) }
391 }
392}
393
394#[inline(always)]
395fn vector_index_check(index: size_t, len: size_t) -> Result<()> {
396 if index >= len {
397 Err(crate::Error::new(
398 crate::core::StsOutOfRange,
399 format!("Index: {index} out of bounds: 0..{len}"),
400 ))
401 } else {
402 Ok(())
403 }
404}