rlst/traits/
data_container.rs

1//! Traits for data containers.
2//!
3//! A [DataContainer] is a low-level interface to physical data. Its derived
4//! traits [ValueDataContainer], [RefDataContainer], and [RefDataContainerMut]
5//! provides value-based access, reference based access, or mutable reference based access.
6//! The [ModifiableDataContainer] defines a setter routine that can modify elements by value.
7//! By default a data container is not resizeable. To define a resizeable data container implement
8//! the [ResizeableDataContainer] trait. For raw access to the underlying data the traits
9//! [RawAccessDataContainer] and [MutableRawAccessDataContainer] are provided.
10//! The [ContainerType] trait attaches an associated type that can be used to distinguish between containers
11//! on a type level.
12
13use crate::{Array, MutableArrayImpl, RawAccessMut, Stride};
14
15/// Base trait for a data container. It defines the type of the underlying data
16/// and provides a method to return the number of elements.
17pub trait DataContainer {
18    /// Item type
19    type Item: Copy + Default;
20
21    /// Return the number of elements in the container.
22    fn number_of_elements(&self) -> usize;
23}
24
25/// A data container that provides value based access.
26pub trait ValueDataContainer: DataContainer {
27    /// Access the container unchecked.
28    ///
29    /// # Safety
30    /// `index` must not be out of bounds.
31    unsafe fn get_unchecked_value(&self, index: usize) -> Self::Item;
32}
33
34/// A data container that provides reference based access.
35pub trait RefDataContainer: DataContainer {
36    /// Access the container by reference
37    ///
38    /// # Safety
39    /// `index` must not be out of bounds.
40    unsafe fn get_unchecked(&self, index: usize) -> &Self::Item;
41}
42
43/// A data container that provides access by mutable reference.
44pub trait RefDataContainerMut: DataContainer {
45    /// Access the container mutably unchecked.
46    ///
47    /// # Safety
48    /// `index` must not be out of bounds.
49    unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut Self::Item;
50}
51
52/// A data container that can modify data by value.
53pub trait ModifiableDataContainer: DataContainer {
54    /// Set the value at a given index.
55    ///
56    /// # Safety
57    /// `index` must not be out of bounds.
58    unsafe fn set_unchecked_value(&mut self, index: usize, value: Self::Item);
59}
60
61/// A resizeable data container that can change its size at runtime.
62pub trait ResizeableDataContainer: DataContainer {
63    /// Resize the data container by providing the new length in `new_len`.
64    fn resize(&mut self, new_len: usize);
65}
66
67/// A data container that provides raw access to the data slice.
68pub trait RawAccessDataContainer: DataContainer {
69    /// Return the data slice for the data container.
70    ///
71    /// Returns `None` if data is not available as contigous slice.
72    fn data(&self) -> Option<&[Self::Item]>;
73}
74
75/// A data container that provides mutable raw access to the data slice.
76pub trait MutableRawAccessDataContainer: RawAccessDataContainer {
77    /// Return the mutable data slice for the data container.
78    ///
79    /// Returns `None` if data is not available as contigous slice.
80    fn data_mut(&mut self) -> Option<&mut [Self::Item]>;
81}
82
83/// Stores the type of a container.
84pub trait ContainerType {
85    /// The type for the container.
86    type Type: ContainerTypeRepr + RowMajorArrayFromContainerType + ArrayFromContainerType;
87
88    /// Returns the type hint for the container as string ref.
89    fn type_as_str(&self) -> &'static str {
90        Self::Type::STR
91    }
92}
93
94/// Associate a string representation with a container type.
95pub trait ContainerTypeRepr {
96    /// The string representation of the container type.
97    const STR: &str;
98}
99
100/// Create a new array from a given container type.
101pub trait ArrayFromContainerType {
102    /// Array Output implementation type
103    type OutputImpl<Item, const NDIM: usize>: MutableArrayImpl<Item, NDIM>
104        + RawAccessMut<Item = Item>
105        + Stride<NDIM>
106    where
107        Item: Copy + Default;
108
109    /// Given the shape, create a new column-major array
110    fn new_arr<Item, const NDIM: usize>(
111        shape: [usize; NDIM],
112    ) -> Array<Self::OutputImpl<Item, NDIM>, NDIM>
113    where
114        Item: Copy + Default;
115}
116
117/// Create a new row-major array from a given container type.
118pub trait RowMajorArrayFromContainerType {
119    /// Array Output type
120    type OutputImpl<Item, const NDIM: usize>: MutableArrayImpl<Item, NDIM>
121        + RawAccessMut<Item = Item>
122        + Stride<NDIM>
123    where
124        Item: Copy + Default;
125
126    /// Given the shape, create a new column-major array
127    fn new_row_major_arr<Item, const NDIM: usize>(
128        shape: [usize; NDIM],
129    ) -> Array<Self::OutputImpl<Item, NDIM>, NDIM>
130    where
131        Item: Copy + Default;
132}
133
134/// Selects a container type based on two other container types.
135pub trait ContainerTypeSelector<U: ContainerTypeRepr, V: ContainerTypeRepr> {
136    /// Select the container type.
137    type Type: ContainerTypeRepr + ArrayFromContainerType + RowMajorArrayFromContainerType;
138}