ospf_rust_multiarray/
dummy_vector.rs

1use 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}