1use crate::agreement::{Binding, Mapping, Missing, Read, ReadPlan};
3use crate::buffer::{Buffer, DType, Element, Items, View};
4use crate::error::{Error, Kind};
5use crate::layout::Layout;
6use std::borrow::Cow;
7
8#[derive(Clone)]
10pub struct ArrayView<'a> { layout: &'a Layout, sources: Vec<Binding<'a>>, plan: ReadPlan }
11
12impl<'a> ArrayView<'a> {
13 pub fn new(layout: &'a Layout, sources: Vec<Binding<'a>>, plan: ReadPlan) -> Result<Self, Error> {
14 if layout.count() != plan.len() { return Err(Error::new(Kind::Length, "read plan doesn't fit its layout")); }
15 Ok(Self { layout, sources, plan })
16 }
17 pub fn compact(layout: &'a Layout, storage: View<'a>) -> Self {
18 Self { layout, sources: vec![Binding::full(storage)], plan: ReadPlan::input(0, storage.len()) }
19 }
20 pub fn layout(&self) -> &'a Layout { self.layout }
21 pub fn dtype(&self) -> DType { self.sources[0].view.dtype() }
22 pub fn len(&self) -> usize { self.plan.len() }
23 pub fn is_empty(&self) -> bool { self.plan.is_empty() }
24 pub fn read(&self) -> Read<'_> { Read { sources: &self.sources, plan: &self.plan } }
25 pub fn plan(&self) -> &ReadPlan { &self.plan }
26 pub fn sources(&self) -> &[Binding<'a>] { &self.sources }
27 pub fn with_layout<'b>(&self, layout: &'b Layout) -> Result<ArrayView<'b>, Error> where 'a: 'b {
29 ArrayView::new(layout, self.sources.clone(), self.plan.clone())
30 }
31 pub fn remapped(&self, mapping: Mapping, items: usize) -> Self {
33 let mut sources = self.sources.clone();
34 let missing = Missing::prototype(self.dtype(), &mut sources);
35 Self { layout: self.layout, sources, plan: self.plan.remapped(mapping, items, missing) }
36 }
37 pub fn contiguous(&self) -> Option<View<'a>> {
38 if self.is_empty() { return Some(self.sources[0].view.slice(0..0)); }
39 let (source, range) = self.plan.contiguous(0..self.len())?;
40 self.sources.get(source)?.borrow(range)
41 }
42 pub fn affine(&self) -> Option<(View<'a>, usize, Vec<isize>)> {
43 let (source, base, strides) = self.plan.affine(self.layout.shape())?;
44 let (view, base) = self.sources.get(source)?.affine(base, &strides, self.layout.shape())?;
45 Some((view, base, strides))
46 }
47 pub fn cast(&self, dtype: DType) -> Result<Items<'a>, Error> {
49 if dtype == self.dtype() && let Some(view) = self.contiguous() { return Ok(Items::Borrowed(view)); }
50 let mut buffer = Buffer::with_capacity(dtype, self.len());
51 self.read().read_into(0..self.len(), dtype, true, &mut buffer)?;
52 Ok(Items::Owned(buffer))
53 }
54 pub fn items<T: Element>(&self) -> Result<Cow<'a, [T]>, Error> { Ok(self.cast(T::DTYPE)?.items()) }
55}