use super::*;
use crate::{Idx, assert};
extern crate alloc;
#[derive(Debug, Clone)]
pub struct Own<I: Index, N: Shape = usize> {
pub(super) forward: alloc::boxed::Box<[N::Idx<I>]>,
pub(super) inverse: alloc::boxed::Box<[N::Idx<I>]>,
}
impl<I: Index, N: Shape> Perm<I, N> {
#[inline]
pub fn as_shape<M: Shape>(&self, dim: M) -> PermRef<'_, I, M> {
self.as_ref().as_shape(dim)
}
#[inline]
pub fn into_shape<M: Shape>(self, dim: M) -> Perm<I, M> {
assert!(self.len().unbound() == dim.unbound());
Perm {
0: Own {
forward: unsafe {
alloc::boxed::Box::from_raw(alloc::boxed::Box::into_raw(
self.0.forward,
) as _)
},
inverse: unsafe {
alloc::boxed::Box::from_raw(alloc::boxed::Box::into_raw(
self.0.inverse,
) as _)
},
},
}
}
#[inline]
#[track_caller]
pub fn new_checked(
forward: alloc::boxed::Box<[Idx<N, I>]>,
inverse: alloc::boxed::Box<[Idx<N, I>]>,
dim: N,
) -> Self {
PermRef::<'_, I, N>::new_checked(&forward, &inverse, dim);
Self {
0: Own { forward, inverse },
}
}
#[inline]
#[track_caller]
pub unsafe fn new_unchecked(
forward: alloc::boxed::Box<[Idx<N, I>]>,
inverse: alloc::boxed::Box<[Idx<N, I>]>,
) -> Self {
let n = forward.len();
assert!(all(
forward.len() == inverse.len(),
n <= I::Signed::MAX.zx(),
));
Self {
0: Own { forward, inverse },
}
}
#[inline]
pub fn into_arrays(
self,
) -> (
alloc::boxed::Box<[Idx<N, I>]>,
alloc::boxed::Box<[Idx<N, I>]>,
) {
(self.0.forward, self.0.inverse)
}
#[inline]
pub fn arrays(&self) -> (&[Idx<N, I>], &[Idx<N, I>]) {
(&self.0.forward, &self.0.inverse)
}
#[inline]
pub fn len(&self) -> N {
unsafe { N::new_unbound(self.0.forward.len()) }
}
#[inline]
pub fn into_inverse(self) -> Self {
Self {
0: Own {
forward: self.0.inverse,
inverse: self.0.forward,
},
}
}
#[inline]
pub fn inverse(&self) -> PermRef<'_, I, N> {
self.rb().inverse()
}
#[inline]
pub fn transpose(&self) -> PermRef<'_, I, N> {
self.rb().transpose()
}
}
impl<'short, I: Index, N: Shape> Reborrow<'short> for Own<I, N> {
type Target = Ref<'short, I, N>;
#[inline]
fn rb(&'short self) -> Self::Target {
Ref {
forward: &self.forward,
inverse: &self.inverse,
}
}
}