use super::dim_u32;
use crate::dimension::DimensionKind;
use crate::error::SolverError;
use crate::scalar::BaseScalar;
#[allow(clippy::len_without_is_empty)]
pub trait VectorAccess {
type Scalar: BaseScalar;
fn len(&self) -> usize;
fn dimension_kind(&self) -> DimensionKind;
fn get(&self, index: usize) -> Result<Self::Scalar, SolverError>;
}
pub trait VectorAccessMut: VectorAccess {
fn set(&mut self, index: usize, value: Self::Scalar) -> Result<(), SolverError>;
}
pub trait ContiguousVectorAccess: VectorAccess {
fn as_contiguous(&self) -> Option<&[Self::Scalar]>;
}
pub trait ContiguousVectorAccessMut: ContiguousVectorAccess + VectorAccessMut {
fn as_contiguous_mut(&mut self) -> Option<&mut [Self::Scalar]>;
}
#[derive(Copy, Clone, Debug)]
pub struct VectorView<'a, S: BaseScalar> {
data: &'a [S],
}
impl<'a, S: BaseScalar> VectorView<'a, S> {
#[inline]
pub fn from_slice(data: &'a [S]) -> Self {
Self { data }
}
#[inline]
pub fn as_slice(&self) -> &'a [S] {
self.data
}
}
impl<S: BaseScalar> VectorAccess for VectorView<'_, S> {
type Scalar = S;
#[inline]
fn len(&self) -> usize {
self.data.len()
}
#[inline]
fn dimension_kind(&self) -> DimensionKind {
DimensionKind::Dynamic
}
#[inline]
fn get(&self, index: usize) -> Result<S, SolverError> {
match self.data.get(index) {
Some(&value) => Ok(value),
None => Err(SolverError::DimensionMismatch {
lhs: dim_u32(index)?,
rhs: dim_u32(self.data.len())?,
}),
}
}
}
impl<S: BaseScalar> ContiguousVectorAccess for VectorView<'_, S> {
#[inline]
fn as_contiguous(&self) -> Option<&[S]> {
Some(self.data)
}
}
#[derive(Debug)]
pub struct VectorViewMut<'a, S: BaseScalar> {
data: &'a mut [S],
}
impl<'a, S: BaseScalar> VectorViewMut<'a, S> {
#[inline]
pub fn from_slice_mut(data: &'a mut [S]) -> Self {
Self { data }
}
}
impl<S: BaseScalar> VectorAccess for VectorViewMut<'_, S> {
type Scalar = S;
#[inline]
fn len(&self) -> usize {
self.data.len()
}
#[inline]
fn dimension_kind(&self) -> DimensionKind {
DimensionKind::Dynamic
}
#[inline]
fn get(&self, index: usize) -> Result<S, SolverError> {
match self.data.get(index) {
Some(&value) => Ok(value),
None => Err(SolverError::DimensionMismatch {
lhs: dim_u32(index)?,
rhs: dim_u32(self.data.len())?,
}),
}
}
}
impl<S: BaseScalar> VectorAccessMut for VectorViewMut<'_, S> {
#[inline]
fn set(&mut self, index: usize, value: S) -> Result<(), SolverError> {
let len = self.data.len();
match self.data.get_mut(index) {
Some(slot) => {
*slot = value;
Ok(())
}
None => Err(SolverError::DimensionMismatch {
lhs: dim_u32(index)?,
rhs: dim_u32(len)?,
}),
}
}
}
impl<S: BaseScalar> ContiguousVectorAccess for VectorViewMut<'_, S> {
#[inline]
fn as_contiguous(&self) -> Option<&[S]> {
Some(&*self.data)
}
}
impl<S: BaseScalar> ContiguousVectorAccessMut for VectorViewMut<'_, S> {
#[inline]
fn as_contiguous_mut(&mut self) -> Option<&mut [S]> {
Some(&mut *self.data)
}
}