GCC Code Coverage Report


Directory: ./
File: firmware/libfirmware/util/include/rusefi/expected.h
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 88.5% 46 0 52
Functions: 90.0% 18 0 20
Branches: 55.6% 10 0 18
Decisions: 62.5% 5 - 8

Line Branch Decision Exec Source
1 /**
2 * @file expected.h
3 * @brief This utility class provides a way for a function to accept or return a value that may be invalid.
4 *
5 * For example, suppose there needs to be a solution for prevention of divide by zero. One could write this function:
6 *
7 * expected<int> my_divide(int num, int denom) {
8 * if (denom == 0) return unexpected;
9 * return num / denom;
10 * }
11 *
12 * todo: how does this compare to std::optional?
13 *
14 * @date April 18, 2020
15 * @author Matthew Kennedy, (c) 2020
16 */
17
18 #pragma once
19
20 struct unexpected_t {};
21
22 enum class UnexpectedCode : char {
23 Unknown = 0,
24
25 // Too much time has passed
26 Timeout,
27
28 // The decoded value was impossibly high/low
29 High,
30 Low,
31
32 // An inconsistency was detected using multiple sources of information
33 Inconsistent,
34
35 // A value is unavailable due to configuration
36 Configuration,
37 };
38 template <class TValue>
39 struct expected {
40 bool Valid;
41
42 union {
43 TValue Value;
44 UnexpectedCode Code;
45 };
46
47 // Implicit constructor to construct in the invalid state
48 111853 constexpr expected(const unexpected_t&) : Valid(false), Code{UnexpectedCode::Unknown} {}
49
50 34005788 constexpr expected(UnexpectedCode code) : Valid(false), Code{code} {}
51
52 // Implicit constructor to convert from TValue (for valid values, so an expected<T> behaves like a T)
53 2008052 constexpr expected(TValue validValue)
54 2008052 : Valid(true)
55 2008052 , Value(validValue)
56 {
57 2008052 }
58
59 // Implicit conversion operator to bool, so you can do things like if (myResult) { ... }
60 742913 constexpr explicit operator bool() const {
61 742913 return Valid;
62 }
63
64 // Easy default value handling
65 35877652 constexpr TValue value_or(TValue valueIfInvalid) const {
66
3/6
expected<float>::value_or(float) const:
✓ Branch 0 taken 1876042 times.
✓ Branch 1 taken 34001607 times.
expected<int>::value_or(int) const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
expected<long>::value_or(long) const:
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
35877652 return Valid ? Value : valueIfInvalid;
67 }
68
69 32 bool operator ==(const expected<TValue>& other) const {
70 // If validity mismatch, not equal
71
2/4
expected<float>::operator==(expected<float> const&) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
expected<long>::operator==(expected<long> const&) const:
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2/4
expected<float>::operator==(expected<float> const&) const:
✗ Decision 'true' not taken.
✓ Decision 'false' taken 30 times.
expected<long>::operator==(expected<long> const&) const:
✗ Decision 'true' not taken.
✓ Decision 'false' taken 2 times.
32 if (Valid != other.Valid) {
72 return false;
73 }
74
75 // If both are invalid, they are equal
76
5/8
expected<float>::operator==(expected<float> const&) const:
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
expected<long>::operator==(expected<long> const&) const:
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
3/4
expected<float>::operator==(expected<float> const&) const:
✓ Decision 'true' taken 14 times.
✓ Decision 'false' taken 16 times.
expected<long>::operator==(expected<long> const&) const:
✓ Decision 'true' taken 2 times.
✗ Decision 'false' not taken.
32 if (!Valid && !other.Valid) {
77 16 return true;
78 }
79
80 // Both are guaranteed valid - simply compare values
81 16 return Value == other.Value;
82 }
83 };
84
85 constexpr unexpected_t unexpected{};
86