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/52void 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/10void 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/12void 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/12void 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 |