GCC Code Coverage Report


Directory: ./
File: include/multiindex.hpp
Date: 2026-04-08 15:34:21
Exec Total Coverage
Lines: 36 36 100.0%
Functions: 11 13 84.6%
Branches: 32 32 100.0%

Line Branch Exec Source
1 #pragma once
2
3 #include "types.hpp"
4
5 enum Order { C, FORTRAN };
6
7 82944 template <int d, Order order = C> class Multiindex {
8 public:
9 using IndexArray = Eigen::Array<int, d, 1>;
10
11 887499 const IndexArray operator*() const { return lin2multi(linindex); }
12 887499 Multiindex<d, order> &operator++() {
13 887499 linindex++;
14 887499 return *this;
15 }
16 Multiindex<d, order> operator++(int) {
17 Multiindex<d, order> tmp = *this;
18 ++(*this);
19 return tmp;
20 }
21 friend bool operator==(const Multiindex<d, order> &rhs, const Multiindex<d, order> &lhs) {
22 return rhs.linindex == lhs.linindex;
23 };
24 970443 friend bool operator!=(const Multiindex<d, order> &rhs, const Multiindex<d, order> &lhs) {
25
20/20
✓ Branch 0 taken 15894 times.
✓ Branch 1 taken 741 times.
✓ Branch 2 taken 45243 times.
✓ Branch 3 taken 582 times.
✓ Branch 4 taken 39366 times.
✓ Branch 5 taken 1458 times.
✓ Branch 6 taken 1458 times.
✓ Branch 7 taken 54 times.
✓ Branch 8 taken 27648 times.
✓ Branch 9 taken 3456 times.
✓ Branch 10 taken 3456 times.
✓ Branch 11 taken 432 times.
✓ Branch 12 taken 432 times.
✓ Branch 13 taken 54 times.
✓ Branch 14 taken 205578 times.
✓ Branch 15 taken 7614 times.
✓ Branch 16 taken 487488 times.
✓ Branch 17 taken 60936 times.
✓ Branch 18 taken 60936 times.
✓ Branch 19 taken 7617 times.
970443 return rhs.linindex != lhs.linindex;
26 };
27
28 82943 Multiindex<d, order> &begin() {
29 82944 linindex = 0;
30 return *this;
31 }
32 82944 Multiindex<d, order> &end() {
33 82944 linindex = linsize;
34 return *this;
35 }
36
37 int linindex;
38 int linsize;
39 IndexArray shape;
40 IndexArray stride;
41
42 Multiindex() {}
43
44 33557 Multiindex(const IndexArray &shape)
45 66924 : linsize(1), shape(shape), stride(IndexArray::Zero(shape.size())) {
46 if constexpr (order == C) {
47
2/2
✓ Branch 0 taken 50040 times.
✓ Branch 1 taken 16685 times.
133450 for (int i = shape.size() - 1; i >= 0; --i) {
48 100071 this->stride[i] = this->linsize;
49 100071 this->linsize *= this->shape[i];
50 }
51 }
52 if constexpr (order == FORTRAN) {
53
2/2
✓ Branch 0 taken 267 times.
✓ Branch 1 taken 89 times.
712 for (int i = 0; i < shape.size(); ++i) {
54 534 this->stride[i] = this->linsize;
55 534 this->linsize *= this->shape[i];
56 }
57 }
58 33557 };
59
60 870023 inline int multi2lin(const IndexArray &multi, bool robust = false) const {
61
2/2
✓ Branch 0 taken 847502 times.
✓ Branch 1 taken 22498 times.
870022 if (robust) {
62 // This robust version should be used if multi might contain out-of-bounds indices.
63 // In this case, the multiindex is wrapped to produce a valid linear index.
64 int result = 0;
65
2/2
✓ Branch 0 taken 2542506 times.
✓ Branch 1 taken 847502 times.
3390008 for (int i = 0; i < shape.size(); ++i) {
66 2542506 result += (((multi[i] % shape[i]) + shape[i]) % shape[i]) * stride[i];
67 }
68 return result;
69 }
70 22521 return (multi * stride).sum();
71 }
72
73 903764 inline IndexArray lin2multi(int lin) const {
74 903764 IndexArray result;
75 903764 result.resize(shape.size());
76 903764 result.setZero();
77 if constexpr (order == C) {
78
2/2
✓ Branch 0 taken 432 times.
✓ Branch 1 taken 144 times.
3553406 for (int i = 0; i < shape.size(); ++i) {
79 2665042 result[i] = lin / stride[i];
80 2665042 lin -= result[i] * stride[i];
81 }
82 }
83 if constexpr (order == FORTRAN) {
84
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 60 times.
61596 for (int i = shape.size() - 1; i >= 0; --i) {
85 46197 result[i] = lin / stride[i];
86 46197 lin -= result[i] * stride[i];
87 }
88 }
89 903763 return result;
90 }
91 };
92