qhull_enhanced/types/
set.rs

1use std::ffi::c_void;
2use std::fmt::Debug;
3use std::marker::PhantomData;
4use std::ops::Not;
5
6use crate::helpers::QhTypeRef;
7
8use crate::{sys, Facet, Qh};
9
10/// Represents a set of Qhull elements
11#[derive(Clone, Copy)]
12pub struct Set<'a, T: QhTypeRef> {
13    set: *mut sys::setT,
14    dim: usize,
15    _phantom: PhantomData<&'a T>,
16}
17
18impl<'a, T: QhTypeRef> Debug for Set<'a, T>
19where
20    T: Debug,
21{
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        f.debug_struct(&format!("Set<{}>", std::any::type_name::<T>()))
24            .field("elements:", &self.iter().collect::<Vec<_>>())
25            .finish()
26    }
27}
28
29impl<'a, T: QhTypeRef> Set<'a, T> {
30    pub(crate) fn maybe_new(set: *mut sys::setT, dim: usize) -> Option<Self> {
31        set.is_null().not().then(|| Self {
32            set,
33            dim,
34            _phantom: PhantomData,
35        })
36    }
37
38    /// Iterate over the elements of the set
39    pub fn iter(&self) -> impl Iterator<Item = T> + 'a {
40        SetIterator::new(self)
41    }
42
43    pub fn maxsize(&self) -> i32 {
44        let set = unsafe { &*self.set };
45        set.maxsize
46    }
47
48    pub fn size(&self, qh: &Qh) -> usize {
49        unsafe {
50            sys::qh_setsize(Qh::raw_ptr(qh) as *mut _, self.set) as usize
51        }
52    }
53}
54
55pub(crate) fn dbg_face_set(set: Option<Set<Facet>>) -> Option<Vec<u32>> {
56    set.map(|s| s.iter().map(|f| f.id()).collect())
57}
58
59#[derive(Clone, Copy)]
60struct SetIterator<'a, T: QhTypeRef> {
61    ptr: *mut *mut T::FFIType,
62    dim: usize,
63    _phantom: PhantomData<&'a T>,
64}
65
66impl<'a, T: QhTypeRef> SetIterator<'a, T> {
67    pub fn new(set: &Set<'a, T>) -> Self {
68        let dim = set.dim;
69        assert!(!set.set.is_null());
70        let set = unsafe { &*set.set };
71        let ptr = unsafe { (&(set.e[0].p)) as *const *mut c_void as *mut *mut T::FFIType };
72        Self {
73            ptr,
74            dim,
75            _phantom: PhantomData,
76        }
77    }
78}
79
80impl<'a, T: QhTypeRef> Iterator for SetIterator<'a, T> {
81    type Item = T;
82
83    fn next(&mut self) -> Option<Self::Item> {
84        // TODO comment on how this works (see the corresponding macro in qhull)
85        let value_ptr = unsafe { *self.ptr };
86        let element = T::from_ptr(value_ptr, self.dim);
87        if element.is_some() {
88            self.ptr = unsafe { self.ptr.add(1) };
89        }
90        element
91    }
92}