nalgebra icon indicating copy to clipboard operation
nalgebra copied to clipboard

Safe way to construct a vector or a matrix from an iterator?

Open ShaiAvr opened this issue 3 years ago • 1 comments

Is there a way to create a Matrix or a Vector with the from_iterator function without panicking?

I am making a little wrapper around nalgebra for my own library, and I'd like to create vectors/matrices safely, that is, return a Result rather than panicking on failure. The from_iterator method panics if the iterator isn't long enough, and I couldn't find a variation that doesn't panic.

Right now, I pretty much copied the code in from_iterator and replaced the panicking part with returning Err:

use nalgebra as na;

pub fn from_iterator<I>(value: I) -> Result<Self, DimensionError>
where
    I: IntoIterator<Item = T>,
{
    let mut arr: na::ArrayStorage<MaybeUninit<T>, S, 1> =
        na::DefaultAllocator::allocate_uninit(na::Const::<S>, na::Const::<1>);

    let mut counter = 0;
    for (arr_ptr, e) in arr.as_mut_slice().iter_mut().zip(value) {
        *arr_ptr = MaybeUninit::new(e);
        counter += 1;
    }

    if counter == S {
        unsafe {
            Ok(Self {
                data: na::SVector::from_data(<na::DefaultAllocator as Allocator<
                    T,
                    na::Const<S>,
                    na::Const<1>,
                >>::assume_init(arr)),
            })
        }
    } else {
        Err(DimensionError {
            message: "Not enough data for ".into(),
        })
    }
}

It doesn't look like the best solution. Is there a version of from_iterator that doesn't panic? If not, I'd consider adding it to the library. Something like try_from_iterator. If I really have to implement it myself, I'd like to know if my implementation is as efficient as it could be?

ShaiAvr avatar Jun 21 '22 10:06 ShaiAvr

You shouldn't be using unsafe, from my perspective.

R2-t avatar Jul 31 '22 12:07 R2-t