1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
/*
Appellation: specs <mod>
Contrib: FL03 <jo3mccain@icloud.com>
*/
use crate::data::repr::OwnedArcRepr;
use crate::data::{ArcTensor, BaseTensor, Tensor};
use core::mem::MaybeUninit;
use core::ptr::NonNull;
/// Array representation trait.
///
/// For an array with elements that can be accessed with safe code.
///
/// ***Internal trait, see `RawData`.***
#[allow(clippy::missing_safety_doc)] // not implementable downstream
pub unsafe trait Data: RawData {
/// Converts the array to a uniquely owned array, cloning elements if necessary.
#[doc(hidden)]
#[allow(clippy::wrong_self_convention)]
fn into_owned(self_: BaseTensor<Self>) -> Tensor<Self::Elem>
where
Self::Elem: Clone;
/// Converts the array into `Array<A, D>` if this is possible without
/// cloning the array elements. Otherwise, returns `self_` unchanged.
#[doc(hidden)]
fn try_into_owned_nocopy<D>(
self_: BaseTensor<Self>,
) -> Result<Tensor<Self::Elem>, BaseTensor<Self>>;
/// Return a shared ownership (copy on write) array based on the existing one,
/// cloning elements if necessary.
#[doc(hidden)]
#[allow(clippy::wrong_self_convention)]
fn to_shared(self_: &BaseTensor<Self>) -> ArcTensor<Self::Elem>
where
Self::Elem: Clone;
}
#[allow(clippy::missing_safety_doc)] // not implementable downstream
pub unsafe trait DataMut: Data + RawDataMut {
/// Ensures that the array has unique access to its data.
#[doc(hidden)]
#[inline]
fn ensure_unique<D>(self_: &mut BaseTensor<Self>)
where
Self: Sized,
{
Self::try_ensure_unique(self_)
}
/// Returns whether the array has unique access to its data.
#[doc(hidden)]
#[inline]
#[allow(clippy::wrong_self_convention)] // mut needed for Arc types
fn is_unique(&mut self) -> bool {
self.try_is_unique().unwrap()
}
}
#[allow(clippy::missing_safety_doc)] // not implementable downstream
pub unsafe trait DataOwned: Data {
/// Corresponding owned data with MaybeUninit elements
type MaybeUninit: DataOwned<Elem = MaybeUninit<Self::Elem>>
+ RawDataSubst<Self::Elem, Output = Self>;
#[doc(hidden)]
fn new(elements: Vec<Self::Elem>) -> Self;
/// Converts the data representation to a shared (copy on write)
/// representation, without any copying.
#[doc(hidden)]
fn into_shared(self) -> OwnedArcRepr<Self::Elem>;
}
/// Array representation trait.
///
/// A representation that is a lightweight view.
///
/// ***Internal trait, see `Data`.***
#[allow(clippy::missing_safety_doc)] // not implementable downstream
pub unsafe trait DataShared: Clone + Data + RawDataClone {}
#[allow(clippy::missing_safety_doc)]
pub unsafe trait RawData: Sized {
type Elem;
#[doc(hidden)]
fn _is_pointer_inbounds(&self, ptr: *const Self::Elem) -> bool;
private_decl! {}
}
/// Array representation trait.
///
/// For an array with writable elements.
///
/// ***Internal trait, see `RawData`.***
#[allow(clippy::missing_safety_doc)] // not implementable downstream
pub unsafe trait RawDataMut: RawData {
/// If possible, ensures that the array has unique access to its data.
///
/// The implementer must ensure that if the input is contiguous, then the
/// output has the same strides as input.
///
/// Additionally, if `Self` provides safe mutable access to array elements,
/// then this method **must** panic or ensure that the data is unique.
#[doc(hidden)]
fn try_ensure_unique(_: &mut BaseTensor<Self>)
where
Self: Sized;
/// If possible, returns whether the array has unique access to its data.
///
/// If `Self` provides safe mutable access to array elements, then it
/// **must** return `Some(_)`.
#[doc(hidden)]
fn try_is_unique(&mut self) -> Option<bool>;
}
/// Array representation trait.
///
/// An array representation that can be cloned.
///
/// ***Internal trait, see `RawData`.***
#[allow(clippy::missing_safety_doc)] // not implementable downstream
pub unsafe trait RawDataClone: RawData {
#[doc(hidden)]
/// Unsafe because, `ptr` must point inside the current storage.
unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>);
#[doc(hidden)]
unsafe fn clone_from_with_ptr(
&mut self,
other: &Self,
ptr: NonNull<Self::Elem>,
) -> NonNull<Self::Elem> {
let (data, ptr) = other.clone_with_ptr(ptr);
*self = data;
ptr
}
}
/// Raw Data Subsitution
pub trait RawDataSubst<A>: RawData {
/// The resulting array storage of the same kind but substituted element type
type Output: RawData<Elem = A>;
/// Unsafely translate the data representation from one element
/// representation to another.
///
/// ## Safety
///
/// Caller must ensure the two types have the same representation.
unsafe fn data_subst(self) -> Self::Output;
}