faer/perm/
permown.rs

1use super::*;
2use crate::{Idx, assert};
3
4extern crate alloc;
5
6/// see [`super::Perm`]
7#[derive(Debug, Clone)]
8pub struct Own<I: Index, N: Shape = usize> {
9	pub(super) forward: alloc::boxed::Box<[N::Idx<I>]>,
10	pub(super) inverse: alloc::boxed::Box<[N::Idx<I>]>,
11}
12
13impl<I: Index, N: Shape> Perm<I, N> {
14	/// returns the input permutation with the given shape after checking that it matches the
15	/// current shape
16	#[inline]
17	pub fn as_shape<M: Shape>(&self, dim: M) -> PermRef<'_, I, M> {
18		self.as_ref().as_shape(dim)
19	}
20
21	/// returns the input permutation with the given shape after checking that it matches the
22	/// current shape
23	#[inline]
24	pub fn into_shape<M: Shape>(self, dim: M) -> Perm<I, M> {
25		assert!(self.len().unbound() == dim.unbound());
26
27		Perm {
28			0: Own {
29				forward: unsafe { alloc::boxed::Box::from_raw(alloc::boxed::Box::into_raw(self.0.forward) as _) },
30				inverse: unsafe { alloc::boxed::Box::from_raw(alloc::boxed::Box::into_raw(self.0.inverse) as _) },
31			},
32		}
33	}
34
35	/// creates a new permutation, by checking the validity of the inputs
36	///
37	/// # panics
38	///
39	/// the function panics if any of the following conditions are violated:
40	/// `forward` and `inverse` must have the same length which must be less than or equal to
41	/// `I::Signed::MAX`, be valid permutations, and be inverse permutations of each other
42	#[inline]
43	#[track_caller]
44	pub fn new_checked(forward: alloc::boxed::Box<[Idx<N, I>]>, inverse: alloc::boxed::Box<[Idx<N, I>]>, dim: N) -> Self {
45		PermRef::<'_, I, N>::new_checked(&forward, &inverse, dim);
46		Self { 0: Own { forward, inverse } }
47	}
48
49	/// creates a new permutation reference, without checking the validity of the inputs
50	///
51	/// # safety
52	///
53	/// `forward` and `inverse` must have the same length which must be less than or equal to
54	/// `I::Signed::MAX`, be valid permutations, and be inverse permutations of each other
55	#[inline]
56	#[track_caller]
57	pub unsafe fn new_unchecked(forward: alloc::boxed::Box<[Idx<N, I>]>, inverse: alloc::boxed::Box<[Idx<N, I>]>) -> Self {
58		let n = forward.len();
59		assert!(all(forward.len() == inverse.len(), n <= I::Signed::MAX.zx(),));
60		Self { 0: Own { forward, inverse } }
61	}
62
63	/// returns the permutation as an array
64	#[inline]
65	pub fn into_arrays(self) -> (alloc::boxed::Box<[Idx<N, I>]>, alloc::boxed::Box<[Idx<N, I>]>) {
66		(self.0.forward, self.0.inverse)
67	}
68
69	/// returns the dimension of the permutation
70	#[inline]
71	pub fn len(&self) -> N {
72		unsafe { N::new_unbound(self.0.forward.len()) }
73	}
74
75	/// returns the inverse permutation
76	#[inline]
77	pub fn into_inverse(self) -> Self {
78		Self {
79			0: Own {
80				forward: self.0.inverse,
81				inverse: self.0.forward,
82			},
83		}
84	}
85}
86
87impl<'short, I: Index, N: Shape> Reborrow<'short> for Own<I, N> {
88	type Target = Ref<'short, I, N>;
89
90	#[inline]
91	fn rb(&'short self) -> Self::Target {
92		Ref {
93			forward: &self.forward,
94			inverse: &self.inverse,
95		}
96	}
97}