rusty_perm/
from_indices.rs1use crate::common::*;
2
3pub trait PermFromIndices<T>
5where
6 Self: Sized,
7{
8 fn from_indices(indices: T) -> Option<Self>;
9}
10
11mod without_std {
12 use super::*;
13 use crate::perm_type::PermS;
14
15 impl<const SIZE: usize> PermFromIndices<[usize; SIZE]> for PermS<SIZE> {
16 fn from_indices(indices: [usize; SIZE]) -> Option<Self> {
18 if !check_indices(indices.as_ref(), &mut [false; SIZE]) {
19 return None;
20 }
21 Some(Self { indices })
22 }
23 }
24
25 impl<const SIZE: usize> PermFromIndices<&[usize; SIZE]> for PermS<SIZE> {
26 fn from_indices(indices: &[usize; SIZE]) -> Option<Self> {
28 Self::from_indices(indices.as_ref())
29 }
30 }
31
32 impl<const SIZE: usize> PermFromIndices<&[usize]> for PermS<SIZE> {
33 fn from_indices(indices: &[usize]) -> Option<Self> {
35 if indices.len() != SIZE {
36 return None;
37 }
38 if !check_indices(indices, &mut [false; SIZE]) {
39 return None;
40 }
41 Some(Self {
42 indices: indices.try_into().unwrap(),
43 })
44 }
45 }
46}
47
48#[cfg(feature = "std")]
49mod with_std {
50 use super::*;
51 use crate::perm_type::{PermD, PermS};
52
53 impl PermFromIndices<Cow<'_, [usize]>> for PermD {
54 fn from_indices(indices: Cow<'_, [usize]>) -> Option<Self> {
56 if !check_indices(indices.as_ref(), &mut vec![false; indices.len()]) {
57 return None;
58 }
59 Some(Self {
60 indices: indices.into_owned(),
61 })
62 }
63 }
64
65 impl PermFromIndices<Vec<usize>> for PermD {
66 fn from_indices(indices: Vec<usize>) -> Option<Self> {
68 if !check_indices(indices.as_slice(), &mut vec![false; indices.len()]) {
69 return None;
70 }
71 Some(Self { indices })
72 }
73 }
74
75 impl PermFromIndices<&'_ [usize]> for PermD {
76 fn from_indices(indices: &[usize]) -> Option<Self> {
78 Self::from_indices(Cow::<'_, [usize]>::from(indices))
79 }
80 }
81
82 impl<const SIZE: usize> PermFromIndices<[usize; SIZE]> for PermD {
83 fn from_indices(indices: [usize; SIZE]) -> Option<Self> {
85 Self::from_indices(indices.as_ref())
86 }
87 }
88
89 impl<const SIZE: usize> PermFromIndices<Vec<usize>> for PermS<SIZE> {
90 fn from_indices(indices: Vec<usize>) -> Option<Self> {
92 let indices: &[usize] = indices.as_ref();
93 Self::from_indices(indices)
94 }
95 }
96
97 impl<const SIZE: usize> PermFromIndices<Cow<'_, [usize]>> for PermS<SIZE> {
98 fn from_indices(indices: Cow<'_, [usize]>) -> Option<Self> {
100 Self::from_indices(indices.as_ref())
101 }
102 }
103}
104
105fn check_indices(indices: &[usize], visited: &mut [bool]) -> bool {
106 let len = indices.len();
107 indices.iter().all(|&index| {
108 if index >= len || visited[index] {
109 false
110 } else {
111 visited[index] = true;
112 true
113 }
114 })
115}