ospf_rust_multiarray/
dummy_vector.rs1use std::ops::{
2 Bound, Range, RangeBounds, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
3};
4
5use crate::Shape;
6
7pub trait DummyIndexRange {
8 fn start_bound(&self) -> Bound<isize>;
9 fn end_bound(&self) -> Bound<isize>;
10 fn contains(&self, v: isize) -> bool;
11}
12
13impl<T> DummyIndexRange for T
14where
15 T: RangeBounds<isize>,
16{
17 fn start_bound(&self) -> Bound<isize> {
18 match RangeBounds::start_bound(self) {
19 Bound::Included(value) => Bound::Included(*value),
20 Bound::Excluded(value) => Bound::Excluded(*value),
21 Bound::Unbounded => Bound::Unbounded,
22 }
23 }
24
25 fn end_bound(&self) -> Bound<isize> {
26 match RangeBounds::end_bound(self) {
27 Bound::Included(value) => Bound::Included(*value),
28 Bound::Excluded(value) => Bound::Excluded(*value),
29 Bound::Unbounded => Bound::Unbounded,
30 }
31 }
32
33 fn contains(&self, value: isize) -> bool {
34 RangeBounds::contains(self, &value)
35 }
36}
37
38enum DummyIndexIterator {
39 Continuous(Range<usize>),
40 Discrete(Vec<usize>),
41}
42
43impl DummyIndexIterator {
44 fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = usize> + 'a> {
45 match self {
46 DummyIndexIterator::Continuous(range) => Box::new(range.clone().into_iter()),
47 DummyIndexIterator::Discrete(indexes) => Box::new(indexes.into_iter().map(|x| *x)),
48 }
49 }
50}
51
52pub enum DummyIndex {
53 Index(isize),
54 Range(Box<dyn DummyIndexRange>),
55 IndexArray(Vec<isize>),
56}
57
58impl DummyIndex {
59 fn iterator_of<S: Shape>(&self, shape: &S, dimension: usize) -> DummyIndexIterator {
60 match self {
61 DummyIndex::Index(index) => match shape.actual_index(dimension, *index) {
62 Some(value) => DummyIndexIterator::Continuous(Range {
63 start: value,
64 end: value + 1,
65 }),
66 None => DummyIndexIterator::Continuous(Range { start: 0, end: 1 }),
67 },
68 DummyIndex::Range(range) => {
69 let lower_bound = match range.start_bound() {
70 Bound::Included(value) => shape.actual_index(dimension, value),
71 Bound::Excluded(value) => shape.actual_index(dimension, value - 1),
72 Bound::Unbounded => Some(0),
73 };
74 let upper_bound = match range.end_bound() {
75 Bound::Included(value) => shape.actual_index(dimension, value + 1),
76 Bound::Excluded(value) => shape.actual_index(dimension, value),
77 Bound::Unbounded => Some(shape.len_of_dimension(dimension).unwrap()),
78 };
79 if lower_bound.is_some() && upper_bound.is_some() {
80 DummyIndexIterator::Continuous(Range {
81 start: lower_bound.unwrap(),
82 end: upper_bound.unwrap(),
83 })
84 } else {
85 DummyIndexIterator::Continuous(Range { start: 0, end: 1 })
86 }
87 }
88 DummyIndex::IndexArray(indexes) => DummyIndexIterator::Discrete(
89 indexes
90 .iter()
91 .filter_map(move |index| shape.actual_index(dimension, *index))
92 .collect(),
93 ),
94 }
95 }
96}
97
98impl From<isize> for DummyIndex {
99 fn from(value: isize) -> Self {
100 Self::Index(value)
101 }
102}
103
104impl From<usize> for DummyIndex {
105 fn from(value: usize) -> Self {
106 Self::Index(value as isize)
107 }
108}
109
110impl From<Range<isize>> for DummyIndex {
111 fn from(range: Range<isize>) -> Self {
112 Self::Range(Box::new(range))
113 }
114}
115
116impl From<RangeFrom<isize>> for DummyIndex {
117 fn from(range: RangeFrom<isize>) -> Self {
118 Self::Range(Box::new(range))
119 }
120}
121
122impl From<RangeInclusive<isize>> for DummyIndex {
123 fn from(range: RangeInclusive<isize>) -> Self {
124 Self::Range(Box::new(range))
125 }
126}
127
128impl From<RangeTo<isize>> for DummyIndex {
129 fn from(range: RangeTo<isize>) -> Self {
130 Self::Range(Box::new(range))
131 }
132}
133
134impl From<RangeToInclusive<isize>> for DummyIndex {
135 fn from(range: RangeToInclusive<isize>) -> Self {
136 Self::Range(Box::new(range))
137 }
138}
139
140impl From<RangeFull> for DummyIndex {
141 fn from(range: RangeFull) -> Self {
142 Self::Range(Box::new(range))
143 }
144}
145
146impl From<&[isize]> for DummyIndex {
147 fn from(indexes: &[isize]) -> Self {
148 Self::IndexArray(indexes.to_vec())
149 }
150}
151
152impl From<Vec<isize>> for DummyIndex {
153 fn from(indexes: Vec<isize>) -> Self {
154 Self::IndexArray(indexes)
155 }
156}
157
158pub(crate) struct DummyAccessPolicy<'a, S: Shape> {
159 pub(self) shape: &'a S,
160 pub(self) iterators: Vec<DummyIndexIterator>,
161}
162
163impl<'a, 'b, S: Shape> DummyAccessPolicy<'a, S> {
164 pub(crate) fn new(vector: &'a S::DummyVectorType, shape: &'a S) -> Self {
165 Self {
166 shape,
167 iterators: (0..shape.dimension())
168 .map(|i| vector[i].iterator_of(shape, i))
169 .collect(),
170 }
171 }
172
173 pub(crate) fn iter(&'b self) -> DummyAccessIterator<'a, 'b, S> {
174 DummyAccessIterator::new(self)
175 }
176}
177
178pub(crate) struct DummyAccessIterator<'a, 'b, S: Shape> {
179 pub(self) policy: *const DummyAccessPolicy<'a, S>,
180 pub(self) iterators: Vec<Box<dyn Iterator<Item = usize> + 'b>>,
181 pub(crate) now: S::VectorType,
182}
183
184impl<'a, 'b, S: Shape> DummyAccessIterator<'a, 'b, S> {
185 pub(crate) fn new(policy: &'b DummyAccessPolicy<'a, S>) -> Self {
186 let mut ret = Self {
187 policy,
188 iterators: policy.iterators.iter().map(|iter| iter.iter()).collect(),
189 now: policy.shape.zero(),
190 };
191 for i in 0..(ret.iterators.len() - 1) {
192 ret.now[i] = ret.iterators[i].next().unwrap();
193 }
194 ret
195 }
196
197 pub(crate) fn next(&mut self) -> Option<&S::VectorType> {
198 for i in (0..self.iterators.len()).rev() {
199 match self.iterators[i].next() {
200 Some(value) => {
201 self.now[i] = value;
202 return Some(&self.now);
203 }
204 None => unsafe {
205 self.iterators[i] = (*self.policy).iterators[i].iter();
206 self.now[i] = self.iterators[i].next().unwrap();
207 },
208 }
209 }
210 None
211 }
212}
213
214macro_rules! dummy_index {
215 ($x:literal) => {
216 DummyIndex::from($x as isize)
217 };
218 ($x:expr) => {
219 DummyIndex::from($x)
220 };
221}
222
223#[macro_export]
224macro_rules! dummy {
225 ($($x:expr),*) => {
226 [$(dummy_index!($x),)*]
227 };
228}
229
230#[macro_export]
231macro_rules! dyn_dummy {
232 ($($x:expr),*) => {
233 vec!($(dummy_index!($x),)*)
234 };
235}