Skip to main content

faer/perm/
permown.rs

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