Skip to main content

veryl_analyzer/ir/
shape.rs

1// This implementation refers the following book
2// https://lo48576.gitlab.io/rust-custom-slice-book/
3
4use crate::ir::{Comptime, Expression, Op};
5use crate::value::Value;
6use std::borrow::{Borrow, BorrowMut, Cow, ToOwned};
7use std::fmt;
8use std::ops::{Deref, DerefMut, Index, IndexMut, Range, RangeBounds, RangeFrom};
9use std::rc::Rc;
10use std::sync::Arc;
11use std::vec::Drain;
12use veryl_parser::token_range::TokenRange;
13
14#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
15#[repr(transparent)]
16pub struct ShapeRef([Option<usize>]);
17
18impl ShapeRef {
19    #[inline]
20    #[must_use]
21    pub fn new(x: &[Option<usize>]) -> &Self {
22        unsafe { &*(x as *const [Option<usize>] as *const Self) }
23    }
24
25    #[inline]
26    #[must_use]
27    pub fn new_mut(x: &mut [Option<usize>]) -> &mut Self {
28        unsafe { &mut *(x as *mut [Option<usize>] as *mut Self) }
29    }
30
31    #[inline]
32    #[must_use]
33    pub fn as_slice(&self) -> &[Option<usize>] {
34        &self.0
35    }
36
37    #[inline]
38    #[must_use]
39    pub fn as_mut_slice(&mut self) -> &mut [Option<usize>] {
40        &mut self.0
41    }
42
43    #[inline]
44    pub fn is_empty(&self) -> bool {
45        self.0.is_empty()
46    }
47
48    #[inline]
49    pub fn dims(&self) -> usize {
50        self.0.len()
51    }
52
53    pub fn total(&self) -> Option<usize> {
54        if self.is_empty() {
55            Some(1)
56        } else {
57            let mut ret = 1;
58            for x in &self.0 {
59                if let Some(x) = x {
60                    ret *= x;
61                } else {
62                    return None;
63                }
64            }
65            Some(ret)
66        }
67    }
68
69    #[inline]
70    pub fn get(&self, x: usize) -> Option<&Option<usize>> {
71        self.0.get(x)
72    }
73
74    #[inline]
75    pub fn get_mut(&mut self, x: usize) -> Option<&mut Option<usize>> {
76        self.0.get_mut(x)
77    }
78
79    #[inline]
80    pub fn iter(&self) -> impl ExactSizeIterator<Item = &Option<usize>> + DoubleEndedIterator {
81        self.0.iter()
82    }
83
84    #[inline]
85    pub fn iter_mut(
86        &mut self,
87    ) -> impl ExactSizeIterator<Item = &mut Option<usize>> + DoubleEndedIterator {
88        self.0.iter_mut()
89    }
90
91    #[inline]
92    pub fn first(&self) -> Option<&Option<usize>> {
93        self.0.first()
94    }
95
96    #[inline]
97    pub fn first_mut(&mut self) -> Option<&mut Option<usize>> {
98        self.0.first_mut()
99    }
100
101    #[inline]
102    pub fn last(&self) -> Option<&Option<usize>> {
103        self.0.last()
104    }
105
106    #[inline]
107    pub fn last_mut(&mut self) -> Option<&mut Option<usize>> {
108        self.0.last_mut()
109    }
110
111    pub fn calc_index(&self, index: &[usize]) -> Option<usize> {
112        if self.is_empty() || (self.dims() == 1 && self[0] == Some(1) && index.is_empty()) {
113            Some(0)
114        } else if index.len() != self.dims() {
115            None
116        } else {
117            let mut ret = 0;
118            let mut base = 1;
119            for (i, x) in self.iter().enumerate().rev() {
120                if let Some(x) = x {
121                    ret += index[i] * base;
122                    base *= x;
123                } else {
124                    return None;
125                }
126            }
127            Some(ret)
128        }
129    }
130
131    pub fn calc_index_expr(&self, index: &[Expression]) -> Option<Expression> {
132        if self.is_empty() || (self.dims() == 1 && self[0] == Some(1) && index.is_empty()) {
133            let token = TokenRange::default();
134            let expr = Expression::create_value(Value::new(0, 32, false), token);
135            Some(expr)
136        } else if index.len() != self.dims() {
137            None
138        } else {
139            let mut ret = None;
140            let mut base = 1;
141            for (i, x) in self.iter().enumerate().rev() {
142                if let Some(x) = x {
143                    let index_expr = index[i].clone();
144                    let token = index_expr.token_range();
145                    let comptime = Box::new(Comptime::create_unknown(token));
146                    let base_expr =
147                        Expression::create_value(Value::new(base as u64, 32, false), token);
148                    let expr = Expression::Binary(
149                        Box::new(index_expr),
150                        Op::Mul,
151                        Box::new(base_expr),
152                        comptime.clone(),
153                    );
154
155                    if let Some(x) = ret {
156                        ret = Some(Expression::Binary(
157                            Box::new(x),
158                            Op::Add,
159                            Box::new(expr),
160                            comptime,
161                        ));
162                    } else {
163                        ret = Some(expr);
164                    }
165
166                    base *= x;
167                } else {
168                    return None;
169                }
170            }
171            ret
172        }
173    }
174
175    pub fn calc_range(&self, index: &[usize]) -> Option<(usize, usize)> {
176        if index.len() > self.dims() {
177            None
178        } else if index.len() < self.dims() {
179            let mut beg = index.to_vec();
180            let mut end = index.to_vec();
181            for (i, x) in self.iter().enumerate() {
182                if i >= index.len() {
183                    if let Some(x) = x {
184                        beg.push(0);
185                        end.push(x.saturating_sub(1));
186                    } else {
187                        return None;
188                    }
189                }
190            }
191            let beg = self.calc_index(&beg)?;
192            let end = self.calc_index(&end)?;
193            Some((beg, end))
194        } else {
195            self.calc_index(index).map(|x| (x, x))
196        }
197    }
198}
199
200impl ToOwned for ShapeRef {
201    type Owned = Shape;
202
203    fn to_owned(&self) -> Self::Owned {
204        Shape::new(self.as_slice().to_owned())
205    }
206}
207
208impl<'a> From<&'a [Option<usize>]> for &'a ShapeRef {
209    #[inline]
210    fn from(value: &'a [Option<usize>]) -> Self {
211        ShapeRef::new(value)
212    }
213}
214
215impl<'a, const N: usize> From<&'a [Option<usize>; N]> for &'a ShapeRef {
216    #[inline]
217    fn from(value: &'a [Option<usize>; N]) -> Self {
218        ShapeRef::new(value)
219    }
220}
221
222impl<'a> From<&'a mut [Option<usize>]> for &'a mut ShapeRef {
223    #[inline]
224    fn from(value: &'a mut [Option<usize>]) -> Self {
225        ShapeRef::new_mut(value)
226    }
227}
228
229impl<'a> From<&'a ShapeRef> for &'a [Option<usize>] {
230    #[inline]
231    fn from(value: &'a ShapeRef) -> Self {
232        value.as_slice()
233    }
234}
235
236impl<'a> From<&'a mut ShapeRef> for &'a mut [Option<usize>] {
237    #[inline]
238    fn from(value: &'a mut ShapeRef) -> Self {
239        value.as_mut_slice()
240    }
241}
242
243impl From<&ShapeRef> for Box<ShapeRef> {
244    fn from(value: &ShapeRef) -> Self {
245        let inner_box: Box<[Option<usize>]> = Box::from(value.as_slice());
246        let inner_boxed_ptr: *mut [Option<usize>] = Box::into_raw(inner_box);
247
248        unsafe { Box::from_raw(inner_boxed_ptr as *mut ShapeRef) }
249    }
250}
251
252impl From<&ShapeRef> for Rc<ShapeRef> {
253    fn from(value: &ShapeRef) -> Self {
254        let inner_box: Rc<[Option<usize>]> = Rc::from(value.as_slice());
255        let inner_boxed_ptr: *const [Option<usize>] = Rc::into_raw(inner_box);
256
257        unsafe { Rc::from_raw(inner_boxed_ptr as *const ShapeRef) }
258    }
259}
260
261impl From<&ShapeRef> for Arc<ShapeRef> {
262    fn from(value: &ShapeRef) -> Self {
263        let inner_box: Arc<[Option<usize>]> = Arc::from(value.as_slice());
264        let inner_boxed_ptr: *const [Option<usize>] = Arc::into_raw(inner_box);
265
266        unsafe { Arc::from_raw(inner_boxed_ptr as *const ShapeRef) }
267    }
268}
269
270impl From<Box<[Option<usize>]>> for Box<ShapeRef> {
271    fn from(value: Box<[Option<usize>]>) -> Self {
272        let boxed_ptr = Box::into_raw(value);
273        unsafe { Box::from_raw(boxed_ptr as *mut ShapeRef) }
274    }
275}
276
277impl From<Vec<Option<usize>>> for Box<ShapeRef> {
278    fn from(value: Vec<Option<usize>>) -> Self {
279        value.into_boxed_slice().into()
280    }
281}
282
283impl From<Box<ShapeRef>> for Shape {
284    fn from(value: Box<ShapeRef>) -> Self {
285        let boxed_slice: Box<[Option<usize>]> = value.into();
286        Self::new(Vec::from(boxed_slice))
287    }
288}
289
290impl From<Box<ShapeRef>> for Box<[Option<usize>]> {
291    fn from(value: Box<ShapeRef>) -> Self {
292        let boxed_ptr = Box::into_raw(value);
293        unsafe { Box::from_raw(boxed_ptr as *mut [Option<usize>]) }
294    }
295}
296
297impl From<Box<ShapeRef>> for Vec<Option<usize>> {
298    fn from(value: Box<ShapeRef>) -> Self {
299        let boxed_slice: Box<[Option<usize>]> = value.into();
300        boxed_slice.into()
301    }
302}
303
304impl<'a> From<&'a ShapeRef> for Cow<'a, ShapeRef> {
305    #[inline]
306    fn from(value: &'a ShapeRef) -> Self {
307        Cow::Borrowed(value)
308    }
309}
310
311impl From<Cow<'_, ShapeRef>> for Box<ShapeRef> {
312    fn from(value: Cow<'_, ShapeRef>) -> Self {
313        match value {
314            Cow::Borrowed(x) => x.into(),
315            Cow::Owned(x) => x.into(),
316        }
317    }
318}
319
320impl AsRef<ShapeRef> for ShapeRef {
321    #[inline]
322    fn as_ref(&self) -> &ShapeRef {
323        self
324    }
325}
326
327impl AsMut<ShapeRef> for ShapeRef {
328    #[inline]
329    fn as_mut(&mut self) -> &mut ShapeRef {
330        self
331    }
332}
333
334impl AsRef<[Option<usize>]> for ShapeRef {
335    #[inline]
336    fn as_ref(&self) -> &[Option<usize>] {
337        self.as_slice()
338    }
339}
340
341impl AsMut<[Option<usize>]> for ShapeRef {
342    #[inline]
343    fn as_mut(&mut self) -> &mut [Option<usize>] {
344        self.as_mut_slice()
345    }
346}
347
348impl AsRef<[Option<usize>]> for Box<ShapeRef> {
349    #[inline]
350    fn as_ref(&self) -> &[Option<usize>] {
351        self.as_slice()
352    }
353}
354
355impl AsMut<[Option<usize>]> for Box<ShapeRef> {
356    #[inline]
357    fn as_mut(&mut self) -> &mut [Option<usize>] {
358        self.as_mut_slice()
359    }
360}
361
362impl fmt::Debug for ShapeRef {
363    #[inline]
364    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
365        self.0.fmt(f)
366    }
367}
368
369impl fmt::Display for ShapeRef {
370    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
371        let mut ret = String::new();
372
373        for (i, x) in self.0.iter().enumerate() {
374            if i != 0 {
375                ret.push_str(", ");
376            }
377            if let Some(x) = x {
378                ret.push_str(&x.to_string());
379            } else {
380                ret.push_str("unknown");
381            }
382        }
383
384        ret.fmt(f)
385    }
386}
387
388impl Default for &ShapeRef {
389    fn default() -> Self {
390        ShapeRef::new(<&[Option<usize>]>::default())
391    }
392}
393
394impl Default for &mut ShapeRef {
395    fn default() -> Self {
396        ShapeRef::new_mut(<&mut [Option<usize>]>::default())
397    }
398}
399
400impl Default for Box<ShapeRef> {
401    fn default() -> Self {
402        <&ShapeRef>::default().into()
403    }
404}
405
406impl Index<usize> for ShapeRef {
407    type Output = Option<usize>;
408
409    fn index(&self, index: usize) -> &Self::Output {
410        &self.0[index]
411    }
412}
413
414impl IndexMut<usize> for ShapeRef {
415    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
416        &mut self.0[index]
417    }
418}
419
420impl Index<RangeFrom<usize>> for ShapeRef {
421    type Output = [Option<usize>];
422
423    fn index(&self, index: RangeFrom<usize>) -> &Self::Output {
424        &self.0[index]
425    }
426}
427
428impl IndexMut<RangeFrom<usize>> for ShapeRef {
429    fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut Self::Output {
430        &mut self.0[index]
431    }
432}
433
434impl Index<Range<usize>> for ShapeRef {
435    type Output = [Option<usize>];
436
437    fn index(&self, index: Range<usize>) -> &Self::Output {
438        &self.0[index]
439    }
440}
441
442impl IndexMut<Range<usize>> for ShapeRef {
443    fn index_mut(&mut self, index: Range<usize>) -> &mut Self::Output {
444        &mut self.0[index]
445    }
446}
447
448#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
449pub struct Shape(Vec<Option<usize>>);
450
451impl Shape {
452    #[inline]
453    #[must_use]
454    pub fn new(x: Vec<Option<usize>>) -> Self {
455        Self(x)
456    }
457
458    #[inline]
459    #[must_use]
460    pub fn as_shape_ref(&self) -> &ShapeRef {
461        ShapeRef::new(self.0.as_slice())
462    }
463
464    #[inline]
465    #[must_use]
466    pub fn as_shape_ref_mut(&mut self) -> &mut ShapeRef {
467        ShapeRef::new_mut(self.0.as_mut_slice())
468    }
469
470    #[inline]
471    pub fn is_empty(&self) -> bool {
472        self.as_shape_ref().is_empty()
473    }
474
475    #[inline]
476    pub fn dims(&self) -> usize {
477        self.as_shape_ref().dims()
478    }
479
480    #[inline]
481    pub fn total(&self) -> Option<usize> {
482        self.as_shape_ref().total()
483    }
484
485    #[inline]
486    pub fn get(&self, x: usize) -> Option<&Option<usize>> {
487        self.as_shape_ref().get(x)
488    }
489
490    #[inline]
491    pub fn get_mut(&mut self, x: usize) -> Option<&mut Option<usize>> {
492        self.as_shape_ref_mut().get_mut(x)
493    }
494
495    #[inline]
496    pub fn iter(&self) -> impl ExactSizeIterator<Item = &Option<usize>> + DoubleEndedIterator {
497        self.as_shape_ref().iter()
498    }
499
500    #[inline]
501    pub fn iter_mut(
502        &mut self,
503    ) -> impl ExactSizeIterator<Item = &mut Option<usize>> + DoubleEndedIterator {
504        self.as_shape_ref_mut().iter_mut()
505    }
506
507    #[inline]
508    pub fn first(&self) -> Option<&Option<usize>> {
509        self.as_shape_ref().first()
510    }
511
512    #[inline]
513    pub fn first_mut(&mut self) -> Option<&mut Option<usize>> {
514        self.as_shape_ref_mut().first_mut()
515    }
516
517    #[inline]
518    pub fn last(&self) -> Option<&Option<usize>> {
519        self.as_shape_ref().last()
520    }
521
522    #[inline]
523    pub fn last_mut(&mut self) -> Option<&mut Option<usize>> {
524        self.as_shape_ref_mut().last_mut()
525    }
526
527    #[inline]
528    pub fn calc_index(&self, index: &[usize]) -> Option<usize> {
529        self.as_shape_ref().calc_index(index)
530    }
531
532    #[inline]
533    pub fn calc_index_expr(&self, index: &[Expression]) -> Option<Expression> {
534        self.as_shape_ref().calc_index_expr(index)
535    }
536
537    #[inline]
538    pub fn calc_range(&self, index: &[usize]) -> Option<(usize, usize)> {
539        self.as_shape_ref().calc_range(index)
540    }
541
542    #[inline]
543    pub fn append(&mut self, x: &mut Shape) {
544        self.0.append(&mut x.0)
545    }
546
547    #[inline]
548    pub fn remove(&mut self, x: usize) -> Option<usize> {
549        self.0.remove(x)
550    }
551
552    #[inline]
553    pub fn clear(&mut self) {
554        self.0.clear()
555    }
556
557    #[inline]
558    pub fn push(&mut self, x: Option<usize>) {
559        self.0.push(x)
560    }
561
562    #[inline]
563    pub fn pop(&mut self) -> Option<Option<usize>> {
564        self.0.pop()
565    }
566
567    #[inline]
568    pub fn replace(&mut self, i: usize, x: Option<usize>) {
569        if i < self.dims() {
570            self.0[i] = x;
571        }
572    }
573
574    #[inline]
575    pub fn drain<R: RangeBounds<usize>>(&mut self, x: R) -> Drain<'_, Option<usize>> {
576        self.0.drain(x)
577    }
578}
579
580impl Borrow<ShapeRef> for Shape {
581    #[inline]
582    fn borrow(&self) -> &ShapeRef {
583        self.as_shape_ref()
584    }
585}
586
587impl BorrowMut<ShapeRef> for Shape {
588    #[inline]
589    fn borrow_mut(&mut self) -> &mut ShapeRef {
590        self.as_shape_ref_mut()
591    }
592}
593
594impl From<Vec<Option<usize>>> for Shape {
595    #[inline]
596    fn from(value: Vec<Option<usize>>) -> Self {
597        Self::new(value)
598    }
599}
600
601impl From<&[Option<usize>]> for Shape {
602    #[inline]
603    fn from(value: &[Option<usize>]) -> Self {
604        Self::new(value.to_owned())
605    }
606}
607
608impl From<Shape> for Vec<Option<usize>> {
609    #[inline]
610    fn from(value: Shape) -> Self {
611        value.0
612    }
613}
614
615impl From<&ShapeRef> for Shape {
616    #[inline]
617    fn from(value: &ShapeRef) -> Self {
618        value.to_owned()
619    }
620}
621
622impl From<&mut ShapeRef> for Shape {
623    #[inline]
624    fn from(value: &mut ShapeRef) -> Self {
625        value.to_owned()
626    }
627}
628
629impl From<&Shape> for Shape {
630    #[inline]
631    fn from(value: &Shape) -> Self {
632        value.clone()
633    }
634}
635
636impl From<Shape> for Box<ShapeRef> {
637    fn from(value: Shape) -> Self {
638        let inner_box: Box<[Option<usize>]> = Box::from(value.0);
639        let inner_boxed_ptr: *mut [Option<usize>] = Box::into_raw(inner_box);
640
641        unsafe { Box::from_raw(inner_boxed_ptr as *mut ShapeRef) }
642    }
643}
644
645impl From<Shape> for Rc<ShapeRef> {
646    fn from(value: Shape) -> Self {
647        let inner_box: Rc<[Option<usize>]> = Rc::from(value.0);
648        let inner_boxed_ptr: *const [Option<usize>] = Rc::into_raw(inner_box);
649
650        unsafe { Rc::from_raw(inner_boxed_ptr as *const ShapeRef) }
651    }
652}
653
654impl From<Shape> for Arc<ShapeRef> {
655    fn from(value: Shape) -> Self {
656        let inner_box: Arc<[Option<usize>]> = Arc::from(value.0);
657        let inner_boxed_ptr: *const [Option<usize>] = Arc::into_raw(inner_box);
658
659        unsafe { Arc::from_raw(inner_boxed_ptr as *const ShapeRef) }
660    }
661}
662
663impl From<Shape> for Cow<'_, ShapeRef> {
664    #[inline]
665    fn from(value: Shape) -> Self {
666        Cow::Owned(value)
667    }
668}
669
670impl<'a> From<&'a Shape> for Cow<'a, ShapeRef> {
671    #[inline]
672    fn from(value: &'a Shape) -> Self {
673        Cow::Borrowed(value.as_shape_ref())
674    }
675}
676
677impl From<Cow<'_, ShapeRef>> for Shape {
678    fn from(value: Cow<'_, ShapeRef>) -> Self {
679        match value {
680            Cow::Borrowed(x) => x.to_owned(),
681            Cow::Owned(x) => x,
682        }
683    }
684}
685
686impl Deref for Shape {
687    type Target = ShapeRef;
688
689    #[inline]
690    fn deref(&self) -> &Self::Target {
691        self.as_shape_ref()
692    }
693}
694
695impl DerefMut for Shape {
696    #[inline]
697    fn deref_mut(&mut self) -> &mut Self::Target {
698        self.as_shape_ref_mut()
699    }
700}
701
702impl AsRef<ShapeRef> for Shape {
703    #[inline]
704    fn as_ref(&self) -> &ShapeRef {
705        self.as_shape_ref()
706    }
707}
708
709impl AsMut<ShapeRef> for Shape {
710    #[inline]
711    fn as_mut(&mut self) -> &mut ShapeRef {
712        self.as_shape_ref_mut()
713    }
714}
715
716impl AsRef<[Option<usize>]> for Shape {
717    #[inline]
718    fn as_ref(&self) -> &[Option<usize>] {
719        self.as_slice()
720    }
721}
722
723impl AsMut<[Option<usize>]> for Shape {
724    #[inline]
725    fn as_mut(&mut self) -> &mut [Option<usize>] {
726        self.as_mut_slice()
727    }
728}
729
730impl fmt::Debug for Shape {
731    #[inline]
732    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
733        self.as_shape_ref().fmt(f)
734    }
735}
736
737impl fmt::Display for Shape {
738    #[inline]
739    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
740        self.as_shape_ref().fmt(f)
741    }
742}
743
744impl PartialEq<&ShapeRef> for &Shape {
745    fn eq(&self, other: &&ShapeRef) -> bool {
746        self.as_shape_ref().eq(other)
747    }
748}
749
750impl Index<usize> for Shape {
751    type Output = Option<usize>;
752
753    fn index(&self, index: usize) -> &Self::Output {
754        &self.0[index]
755    }
756}
757
758impl IndexMut<usize> for Shape {
759    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
760        &mut self.0[index]
761    }
762}
763
764impl Index<RangeFrom<usize>> for Shape {
765    type Output = [Option<usize>];
766    fn index(&self, index: RangeFrom<usize>) -> &Self::Output {
767        &self.0[index]
768    }
769}
770
771impl IndexMut<RangeFrom<usize>> for Shape {
772    fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut Self::Output {
773        &mut self.0[index]
774    }
775}
776
777#[cfg(test)]
778mod tests {
779    use super::*;
780
781    #[test]
782    fn test_calc_index() {
783        let array = Shape::new(vec![Some(2), Some(3), Some(4)]);
784        assert_eq!(array.calc_index(&[0, 0, 0]), Some(0));
785        assert_eq!(array.calc_index(&[0, 0, 1]), Some(1));
786        assert_eq!(array.calc_index(&[0, 0, 2]), Some(2));
787        assert_eq!(array.calc_index(&[0, 0, 3]), Some(3));
788        assert_eq!(array.calc_index(&[0, 1, 0]), Some(4));
789        assert_eq!(array.calc_index(&[0, 1, 1]), Some(5));
790        assert_eq!(array.calc_index(&[0, 1, 2]), Some(6));
791        assert_eq!(array.calc_index(&[0, 1, 3]), Some(7));
792        assert_eq!(array.calc_index(&[0, 2, 0]), Some(8));
793        assert_eq!(array.calc_index(&[0, 2, 1]), Some(9));
794        assert_eq!(array.calc_index(&[0, 2, 2]), Some(10));
795        assert_eq!(array.calc_index(&[0, 2, 3]), Some(11));
796        assert_eq!(array.calc_index(&[1, 0, 0]), Some(12));
797        assert_eq!(array.calc_index(&[1, 0, 1]), Some(13));
798        assert_eq!(array.calc_index(&[1, 0, 2]), Some(14));
799        assert_eq!(array.calc_index(&[1, 0, 3]), Some(15));
800        assert_eq!(array.calc_index(&[1, 1, 0]), Some(16));
801        assert_eq!(array.calc_index(&[1, 1, 1]), Some(17));
802        assert_eq!(array.calc_index(&[1, 1, 2]), Some(18));
803        assert_eq!(array.calc_index(&[1, 1, 3]), Some(19));
804        assert_eq!(array.calc_index(&[1, 2, 0]), Some(20));
805        assert_eq!(array.calc_index(&[1, 2, 1]), Some(21));
806        assert_eq!(array.calc_index(&[1, 2, 2]), Some(22));
807        assert_eq!(array.calc_index(&[1, 2, 3]), Some(23));
808    }
809
810    #[test]
811    fn test_calc_range() {
812        let array = Shape::new(vec![Some(2), Some(3), Some(4)]);
813        assert_eq!(array.calc_range(&[0, 0, 0]), Some((0, 0)));
814        assert_eq!(array.calc_range(&[0, 0, 1]), Some((1, 1)));
815        assert_eq!(array.calc_range(&[0, 0, 2]), Some((2, 2)));
816        assert_eq!(array.calc_range(&[0, 0, 3]), Some((3, 3)));
817        assert_eq!(array.calc_range(&[0, 1, 0]), Some((4, 4)));
818        assert_eq!(array.calc_range(&[0, 1, 1]), Some((5, 5)));
819        assert_eq!(array.calc_range(&[0, 1, 2]), Some((6, 6)));
820        assert_eq!(array.calc_range(&[0, 1, 3]), Some((7, 7)));
821        assert_eq!(array.calc_range(&[0, 2, 0]), Some((8, 8)));
822        assert_eq!(array.calc_range(&[0, 2, 1]), Some((9, 9)));
823        assert_eq!(array.calc_range(&[0, 2, 2]), Some((10, 10)));
824        assert_eq!(array.calc_range(&[0, 2, 3]), Some((11, 11)));
825        assert_eq!(array.calc_range(&[1, 0, 0]), Some((12, 12)));
826        assert_eq!(array.calc_range(&[1, 0, 1]), Some((13, 13)));
827        assert_eq!(array.calc_range(&[1, 0, 2]), Some((14, 14)));
828        assert_eq!(array.calc_range(&[1, 0, 3]), Some((15, 15)));
829        assert_eq!(array.calc_range(&[1, 1, 0]), Some((16, 16)));
830        assert_eq!(array.calc_range(&[1, 1, 1]), Some((17, 17)));
831        assert_eq!(array.calc_range(&[1, 1, 2]), Some((18, 18)));
832        assert_eq!(array.calc_range(&[1, 1, 3]), Some((19, 19)));
833        assert_eq!(array.calc_range(&[1, 2, 0]), Some((20, 20)));
834        assert_eq!(array.calc_range(&[1, 2, 1]), Some((21, 21)));
835        assert_eq!(array.calc_range(&[1, 2, 2]), Some((22, 22)));
836        assert_eq!(array.calc_range(&[1, 2, 3]), Some((23, 23)));
837        assert_eq!(array.calc_range(&[0, 0]), Some((0, 3)));
838        assert_eq!(array.calc_range(&[0, 1]), Some((4, 7)));
839        assert_eq!(array.calc_range(&[0, 2]), Some((8, 11)));
840        assert_eq!(array.calc_range(&[1, 0]), Some((12, 15)));
841        assert_eq!(array.calc_range(&[1, 1]), Some((16, 19)));
842        assert_eq!(array.calc_range(&[1, 2]), Some((20, 23)));
843        assert_eq!(array.calc_range(&[0]), Some((0, 11)));
844        assert_eq!(array.calc_range(&[1]), Some((12, 23)));
845        assert_eq!(array.calc_range(&[]), Some((0, 23)));
846    }
847}