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