GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 92.8% 284 / 0 / 306
Functions: 91.1% 72 / 1 / 80
Branches: 95.0% 76 / 0 / 80
Decisions: 85.7% 12 / - / 14

firmware/libfirmware/util/include/rusefi/arrays.h
Line Branch Decision Exec Source
1 #pragma once
2
3 #include <cstddef>
4 #include <cstring>
5 #include <cmath>
6
7 #include "scaled_channel.h"
8 #include "critical_error.h"
9
10 /**
11 * Copies an array from src to dest. The lengths of the arrays must match.
12 */
13 template <typename DElement, typename SElement, size_t N>
14 24792 constexpr void copyArray(DElement (&dest)[N], const SElement (&src)[N]) {
15
48/52
void copyArray<scaled_channel<int, 10, 1>, int, 2ul>(scaled_channel<int, 10, 1> (&) [2ul], int const (&) [2ul]):
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
void copyArray<scaled_channel<short, 1, 1>, float, 16ul>(scaled_channel<short, 1, 1> (&) [16ul], float const (&) [16ul]):
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 15 times.
void copyArray<scaled_channel<short, 1, 1>, int, 16ul>(scaled_channel<short, 1, 1> (&) [16ul], int const (&) [16ul]):
✓ Branch 0 taken 9616 times.
✓ Branch 1 taken 601 times.
void copyArray<scaled_channel<short, 1, 1>, int, 4ul>(scaled_channel<short, 1, 1> (&) [4ul], int const (&) [4ul]):
✓ Branch 0 taken 2408 times.
✓ Branch 1 taken 602 times.
void copyArray<scaled_channel<short, 1, 1>, signed char, 8ul>(scaled_channel<short, 1, 1> (&) [8ul], signed char const (&) [8ul]):
✓ Branch 0 taken 4808 times.
✓ Branch 1 taken 601 times.
void copyArray<scaled_channel<short, 10, 1>, double, 5ul>(scaled_channel<short, 10, 1> (&) [5ul], double const (&) [5ul]):
✓ Branch 0 taken 15025 times.
✓ Branch 1 taken 3005 times.
void copyArray<scaled_channel<short, 10, 1>, double, 8ul>(scaled_channel<short, 10, 1> (&) [8ul], double const (&) [8ul]):
✓ Branch 0 taken 38464 times.
✓ Branch 1 taken 4808 times.
void copyArray<scaled_channel<short, 100, 1>, float, 8ul>(scaled_channel<short, 100, 1> (&) [8ul], float const (&) [8ul]):
✓ Branch 0 taken 14496 times.
✓ Branch 1 taken 1812 times.
void copyArray<scaled_channel<signed char, 10, 1>, int, 4ul>(scaled_channel<signed char, 10, 1> (&) [4ul], int const (&) [4ul]):
✓ Branch 0 taken 9616 times.
✓ Branch 1 taken 2404 times.
void copyArray<scaled_channel<unsigned char, 1, 100>, float, 16ul>(scaled_channel<unsigned char, 1, 100> (&) [16ul], float const (&) [16ul]):
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 15 times.
void copyArray<scaled_channel<unsigned char, 1, 100>, float, 8ul>(scaled_channel<unsigned char, 1, 100> (&) [8ul], float const (&) [8ul]):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
void copyArray<scaled_channel<unsigned char, 1, 20>, float, 16ul>(scaled_channel<unsigned char, 1, 20> (&) [16ul], float const (&) [16ul]):
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 15 times.
void copyArray<scaled_channel<unsigned char, 1, 20>, int, 16ul>(scaled_channel<unsigned char, 1, 20> (&) [16ul], int const (&) [16ul]):
✓ Branch 0 taken 9616 times.
✓ Branch 1 taken 601 times.
void copyArray<scaled_channel<unsigned char, 1, 5>, unsigned short, 8ul>(scaled_channel<unsigned char, 1, 5> (&) [8ul], unsigned short const (&) [8ul]):
✓ Branch 0 taken 4808 times.
✓ Branch 1 taken 601 times.
void copyArray<scaled_channel<unsigned char, 100, 1>, float, 8ul>(scaled_channel<unsigned char, 100, 1> (&) [8ul], float const (&) [8ul]):
✓ Branch 0 taken 19232 times.
✓ Branch 1 taken 2404 times.
void copyArray<scaled_channel<unsigned char, 2, 1>, float, 16ul>(scaled_channel<unsigned char, 2, 1> (&) [16ul], float const (&) [16ul]):
✓ Branch 0 taken 9856 times.
✓ Branch 1 taken 616 times.
void copyArray<scaled_channel<unsigned char, 50, 1>, float, 8ul>(scaled_channel<unsigned char, 50, 1> (&) [8ul], float const (&) [8ul]):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
void copyArray<scaled_channel<unsigned int, 10, 1>, float, 2ul>(scaled_channel<unsigned int, 10, 1> (&) [2ul], float const (&) [2ul]):
✓ Branch 0 taken 2422 times.
✓ Branch 1 taken 1211 times.
void copyArray<scaled_channel<unsigned short, 100, 1>, float, 8ul>(scaled_channel<unsigned short, 100, 1> (&) [8ul], float const (&) [8ul]):
✓ Branch 0 taken 4808 times.
✓ Branch 1 taken 601 times.
void copyArray<signed char, float, 8ul>(signed char (&) [8ul], float const (&) [8ul]):
✓ Branch 0 taken 4808 times.
✓ Branch 1 taken 601 times.
void copyArray<signed char, int, 8ul>(signed char (&) [8ul], int const (&) [8ul]):
✓ Branch 0 taken 4808 times.
✓ Branch 1 taken 601 times.
void copyArray<unsigned short, float, 16ul>(unsigned short (&) [16ul], float const (&) [16ul]):
✓ Branch 0 taken 10368 times.
✓ Branch 1 taken 648 times.
void copyArray<unsigned short, float, 4ul>(unsigned short (&) [4ul], float const (&) [4ul]):
✓ Branch 0 taken 2404 times.
✓ Branch 1 taken 601 times.
void copyArray<unsigned short, float, 8ul>(unsigned short (&) [8ul], float const (&) [8ul]):
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 16 times.
void copyArray<unsigned short, int, 4ul>(unsigned short (&) [4ul], int const (&) [4ul]):
✓ Branch 0 taken 9620 times.
✓ Branch 1 taken 2405 times.
void copyArray<unsigned short, unsigned char, 16ul>(unsigned short (&) [16ul], unsigned char const (&) [16ul]):
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 7 times.
8/10
void copyArray<scaled_channel<int, 10, 1>, int, 2ul>(scaled_channel<int, 10, 1> (&) [2ul], int const (&) [2ul]):
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 1 time.
void copyArray<scaled_channel<short, 1, 1>, int, 4ul>(scaled_channel<short, 1, 1> (&) [4ul], int const (&) [4ul]):
✓ Decision 'true' taken 2408 times.
✓ Decision 'false' taken 602 times.
void copyArray<scaled_channel<unsigned char, 2, 1>, float, 16ul>(scaled_channel<unsigned char, 2, 1> (&) [16ul], float const (&) [16ul]):
✓ Decision 'true' taken 9856 times.
✓ Decision 'false' taken 616 times.
void copyArray<unsigned short, float, 16ul>(unsigned short (&) [16ul], float const (&) [16ul]):
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
void copyArray<unsigned short, unsigned char, 16ul>(unsigned short (&) [16ul], unsigned char const (&) [16ul]):
✓ Decision 'true' taken 112 times.
✓ Decision 'false' taken 7 times.
202937 for (size_t i = 0; i < N; i++) {
16 178145 dest[i] = src[i];
17 }
18 24792 }
19
20 // specialization that can use memcpy when src and dest types match
21 template <typename DElement, size_t N>
22 constexpr void copyArray(scaled_channel<DElement, 1, 1> (&dest)[N], const DElement (&src)[N]) {
23 memcpy(dest, src, sizeof(DElement) * N);
24 }
25
26 template <typename DElement, size_t N>
27 3640 constexpr void copyArray(DElement (&dest)[N], const DElement (&src)[N]) {
28 3640 memcpy(dest, src, sizeof(DElement) * N);
29 3640 }
30
31 /**
32 * Copies an array from src to the beginning of dst. If dst is larger
33 * than src, then only the elements copied from src will be touched.
34 * Any remaining elements at the end will be untouched.
35 */
36 template <typename TElement, size_t NSrc, size_t NDest>
37 1 constexpr void copyArrayPartial(TElement (&dest)[NDest], const TElement (&src)[NSrc]) {
38 static_assert(NDest >= NSrc, "Source array must be larger than destination.");
39
40
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 1 time.
3 for (size_t i = 0; i < NSrc; i++) {
41 2 dest[i] = src[i];
42 }
43 1 }
44
45 /**
46 * Copies an array from src to dest. The lengths can be different
47 * if dest is larger, the array is interpolated, otherwise, values are stepped to preserve the range
48 * on interpolation we use float and then cast to DElement
49 */
50 template <typename DElement, typename SElement, size_t NDest, size_t NSrc, int roundDigits = 2>
51 5417 constexpr void copyArrayInterpolated(DElement (&dest)[NDest], const SElement (&src)[NSrc]) {
52 if constexpr (NDest == NSrc) {
53 // Same size - direct copy
54 5410 copyArray(dest, src);
55 } else if constexpr (NDest > NSrc) {
56 // Destination larger - interpolate
57 6 const float roundScale = pow(10, roundDigits);
58 6 constexpr float step = static_cast<float>(NSrc - 1) / (NDest - 1);
59
60
12/12
void copyArrayInterpolated<float, float, 3ul, 2ul, 2>(float (&) [3ul], float const (&) [2ul]):
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 time.
void copyArrayInterpolated<float, float, 4ul, 2ul, 1>(float (&) [4ul], float const (&) [2ul]):
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 time.
void copyArrayInterpolated<float, float, 5ul, 2ul, 2>(float (&) [5ul], float const (&) [2ul]):
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 time.
void copyArrayInterpolated<float, float, 7ul, 3ul, 2>(float (&) [7ul], float const (&) [3ul]):
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 time.
void copyArrayInterpolated<float, int, 5ul, 3ul, 2>(float (&) [5ul], int const (&) [3ul]):
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 time.
void copyArrayInterpolated<int, int, 5ul, 2ul, 2>(int (&) [5ul], int const (&) [2ul]):
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 time.
35 for (size_t i = 0; i < NDest; i++) {
61 29 const float currentSrcPos = static_cast<float>(i) * step;
62 29 auto srcIdx = static_cast<size_t>(currentSrcPos);
63 29 const float frac = currentSrcPos - static_cast<float>(srcIdx);
64
65
12/12
void copyArrayInterpolated<float, float, 3ul, 2ul, 2>(float (&) [3ul], float const (&) [2ul]):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 2 times.
void copyArrayInterpolated<float, float, 4ul, 2ul, 1>(float (&) [4ul], float const (&) [2ul]):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 3 times.
void copyArrayInterpolated<float, float, 5ul, 2ul, 2>(float (&) [5ul], float const (&) [2ul]):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 4 times.
void copyArrayInterpolated<float, float, 7ul, 3ul, 2>(float (&) [7ul], float const (&) [3ul]):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 6 times.
void copyArrayInterpolated<float, int, 5ul, 3ul, 2>(float (&) [5ul], int const (&) [3ul]):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 4 times.
void copyArrayInterpolated<int, int, 5ul, 2ul, 2>(int (&) [5ul], int const (&) [2ul]):
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 4 times.
29 if (srcIdx >= NSrc - 1) {
66 6 dest[i] = src[NSrc - 1];
67 } else {
68 23 float interpolated = static_cast<float>(src[srcIdx]) * (1.0f - frac) + static_cast<float>(src[srcIdx + 1]) * frac;
69 if constexpr (roundDigits >= 0) {
70 // Round to specified decimal places
71 23 float rounded = static_cast<float>(static_cast<int>(interpolated * roundScale + 0.5f)) / roundScale;
72 23 dest[i] = static_cast<DElement>(rounded);
73 } else {
74 dest[i] = static_cast<DElement>(interpolated);
75 }
76 }
77 }
78 } else {
79 // Destination smaller - step through source to preserve range
80
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 time.
2/2
✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 1 time.
4 for (size_t i = 0; i < NDest; i++) {
81 3 size_t srcIdx = i * (NSrc - 1) / (NDest - 1);
82 3 dest[i] = src[srcIdx];
83 }
84 }
85 5417 }
86
87 namespace efi
88 {
89 template <typename T, size_t N>
90 452799030 constexpr size_t size(const T(&)[N]) {
91 452799030 return N;
92 }
93
94 // Zero the passed object
95 template <typename T>
96 601 constexpr void clear(T* obj) {
97 #ifdef WE_HAVE_CRITICAL_ERROR_METHOD
98 if (obj == nullptr) {
99 efiCriticalError("clear nullptr");
100 return;
101 }
102 #endif // WE_HAVE_CRITICAL_ERROR_METHOD
103 // The cast to void* is to prevent errors like:
104 // clearing an object of non-trivial type 'struct persistent_config_s'; use assignment or value-initialization instead
105 // This is technically wrong, but we know config objects only ever actually
106 // contain integral types, though they may be wrapped in a scaled_channel
107 601 memset(reinterpret_cast<void*>(obj), 0, sizeof(T));
108 601 }
109
110 template <typename T>
111 constexpr void clear(T& obj) {
112 clear(&obj);
113 }
114 } // namespace efi
115