@@ -613,26 +613,33 @@ template <typename T> Expr<T> Folder<T>::CSHIFT(FunctionRef<T> &&funcRef) {
613
613
}
614
614
if (ok) {
615
615
std::vector<Scalar<T>> resultElements;
616
- ConstantSubscripts arrayAt{array->lbounds ()};
617
- ConstantSubscript dimLB{arrayAt[zbDim]};
616
+ ConstantSubscripts arrayLB{array->lbounds ()};
617
+ ConstantSubscripts arrayAt{arrayLB};
618
+ ConstantSubscript &dimIndex{arrayAt[zbDim]};
619
+ ConstantSubscript dimLB{dimIndex}; // initial value
618
620
ConstantSubscript dimExtent{array->shape ()[zbDim]};
619
- ConstantSubscripts shiftAt{shift->lbounds ()};
620
- for (auto n{GetSize (array->shape ())}; n > 0 ; n -= dimExtent) {
621
- ConstantSubscript shiftCount{shift->At (shiftAt).ToInt64 ()};
622
- ConstantSubscript zbDimIndex{shiftCount % dimExtent};
623
- if (zbDimIndex < 0 ) {
624
- zbDimIndex += dimExtent;
625
- }
626
- for (ConstantSubscript j{0 }; j < dimExtent; ++j) {
627
- arrayAt[zbDim] = dimLB + zbDimIndex;
628
- resultElements.push_back (array->At (arrayAt));
629
- if (++zbDimIndex == dimExtent) {
630
- zbDimIndex = 0 ;
621
+ ConstantSubscripts shiftLB{shift->lbounds ()};
622
+ for (auto n{GetSize (array->shape ())}; n > 0 ; --n) {
623
+ ConstantSubscript origDimIndex{dimIndex};
624
+ ConstantSubscripts shiftAt;
625
+ if (shift->Rank () > 0 ) {
626
+ int k{0 };
627
+ for (int j{0 }; j < rank; ++j) {
628
+ if (j != zbDim) {
629
+ shiftAt.emplace_back (shiftLB[k++] + arrayAt[j] - arrayLB[j]);
630
+ }
631
631
}
632
632
}
633
- arrayAt[zbDim] = dimLB + std::max<ConstantSubscript>(dimExtent, 1 ) - 1 ;
633
+ ConstantSubscript shiftCount{shift->At (shiftAt).ToInt64 ()};
634
+ dimIndex = dimLB + ((dimIndex - dimLB + shiftCount) % dimExtent);
635
+ if (dimIndex < dimLB) {
636
+ dimIndex += dimExtent;
637
+ } else if (dimIndex >= dimLB + dimExtent) {
638
+ dimIndex -= dimExtent;
639
+ }
640
+ resultElements.push_back (array->At (arrayAt));
641
+ dimIndex = origDimIndex;
634
642
array->IncrementSubscripts (arrayAt);
635
- shift->IncrementSubscripts (shiftAt);
636
643
}
637
644
return Expr<T>{PackageConstant<T>(
638
645
std::move (resultElements), *array, array->shape ())};
@@ -714,42 +721,57 @@ template <typename T> Expr<T> Folder<T>::EOSHIFT(FunctionRef<T> &&funcRef) {
714
721
}
715
722
if (ok) {
716
723
std::vector<Scalar<T>> resultElements;
717
- ConstantSubscripts arrayAt{array->lbounds ()};
718
- ConstantSubscript dimLB{arrayAt[zbDim]};
724
+ ConstantSubscripts arrayLB{array->lbounds ()};
725
+ ConstantSubscripts arrayAt{arrayLB};
726
+ ConstantSubscript &dimIndex{arrayAt[zbDim]};
727
+ ConstantSubscript dimLB{dimIndex}; // initial value
719
728
ConstantSubscript dimExtent{array->shape ()[zbDim]};
720
- ConstantSubscripts shiftAt {shift->lbounds ()};
721
- ConstantSubscripts boundaryAt ;
729
+ ConstantSubscripts shiftLB {shift->lbounds ()};
730
+ ConstantSubscripts boundaryLB ;
722
731
if (boundary) {
723
- boundaryAt = boundary->lbounds ();
732
+ boundaryLB = boundary->lbounds ();
724
733
}
725
- for (auto n{GetSize (array->shape ())}; n > 0 ; n -= dimExtent) {
734
+ for (auto n{GetSize (array->shape ())}; n > 0 ; --n) {
735
+ ConstantSubscript origDimIndex{dimIndex};
736
+ ConstantSubscripts shiftAt;
737
+ if (shift->Rank () > 0 ) {
738
+ int k{0 };
739
+ for (int j{0 }; j < rank; ++j) {
740
+ if (j != zbDim) {
741
+ shiftAt.emplace_back (shiftLB[k++] + arrayAt[j] - arrayLB[j]);
742
+ }
743
+ }
744
+ }
726
745
ConstantSubscript shiftCount{shift->At (shiftAt).ToInt64 ()};
727
- for (ConstantSubscript j{0 }; j < dimExtent; ++j) {
728
- ConstantSubscript zbAt{shiftCount + j};
729
- if (zbAt >= 0 && zbAt < dimExtent) {
730
- arrayAt[zbDim] = dimLB + zbAt;
731
- resultElements.push_back (array->At (arrayAt));
732
- } else if (boundary) {
733
- resultElements.push_back (boundary->At (boundaryAt));
734
- } else if constexpr (T::category == TypeCategory::Integer ||
735
- T::category == TypeCategory::Real ||
736
- T::category == TypeCategory::Complex ||
737
- T::category == TypeCategory::Logical) {
738
- resultElements.emplace_back ();
739
- } else if constexpr (T::category == TypeCategory::Character) {
740
- auto len{static_cast <std::size_t >(array->LEN ())};
741
- typename Scalar<T>::value_type space{' ' };
742
- resultElements.emplace_back (len, space);
743
- } else {
744
- DIE (" no derived type boundary" );
746
+ dimIndex += shiftCount;
747
+ if (dimIndex >= dimLB && dimIndex < dimLB + dimExtent) {
748
+ resultElements.push_back (array->At (arrayAt));
749
+ } else if (boundary) {
750
+ ConstantSubscripts boundaryAt;
751
+ if (boundary->Rank () > 0 ) {
752
+ for (int j{0 }; j < rank; ++j) {
753
+ int k{0 };
754
+ if (j != zbDim) {
755
+ boundaryAt.emplace_back (
756
+ boundaryLB[k++] + arrayAt[j] - arrayLB[j]);
757
+ }
758
+ }
745
759
}
760
+ resultElements.push_back (boundary->At (boundaryAt));
761
+ } else if constexpr (T::category == TypeCategory::Integer ||
762
+ T::category == TypeCategory::Real ||
763
+ T::category == TypeCategory::Complex ||
764
+ T::category == TypeCategory::Logical) {
765
+ resultElements.emplace_back ();
766
+ } else if constexpr (T::category == TypeCategory::Character) {
767
+ auto len{static_cast <std::size_t >(array->LEN ())};
768
+ typename Scalar<T>::value_type space{' ' };
769
+ resultElements.emplace_back (len, space);
770
+ } else {
771
+ DIE (" no derived type boundary" );
746
772
}
747
- arrayAt[zbDim] = dimLB + std::max<ConstantSubscript>(dimExtent, 1 ) - 1 ;
773
+ dimIndex = origDimIndex ;
748
774
array->IncrementSubscripts (arrayAt);
749
- shift->IncrementSubscripts (shiftAt);
750
- if (boundary) {
751
- boundary->IncrementSubscripts (boundaryAt);
752
- }
753
775
}
754
776
return Expr<T>{PackageConstant<T>(
755
777
std::move (resultElements), *array, array->shape ())};
0 commit comments