• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

paulmthompson / WhiskerToolbox / 15655387894

14 Jun 2025 07:27PM UTC coverage: 65.21% (+0.6%) from 64.638%
15655387894

push

github

paulmthompson
fixed data aggregation error with DataArrayIndex vs TimeFrameIndex problem

18 of 20 new or added lines in 1 file covered. (90.0%)

183 existing lines in 13 files now uncovered.

7996 of 12262 relevant lines covered (65.21%)

602.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.0
/src/WhiskerToolbox/DataManager/TimeFrame/StrongTimeTypes.hpp
1
#ifndef STRONG_TIME_TYPES_HPP
2
#define STRONG_TIME_TYPES_HPP
3

4
#include <cstdint>
5
#include <cstddef>
6
#include <variant>
7
#include <type_traits>
8

9
/**
10
 * @brief Strong type for camera frame indices
11
 * 
12
 * Represents indices into camera frame sequences. Cannot be directly
13
 * converted to other time coordinate systems without explicit conversion
14
 * through a TimeFrame.
15
 */
16
class CameraFrameIndex {
17
public:
18
    explicit CameraFrameIndex(int64_t value) : _value(value) {}
268✔
19
    
20
    [[nodiscard]] int64_t getValue() const { return _value; }
41✔
21
    
22
    // Comparison operators
23
    bool operator==(CameraFrameIndex const& other) const { return _value == other._value; }
1✔
24
    bool operator!=(CameraFrameIndex const& other) const { return _value != other._value; }
1✔
25
    bool operator<(CameraFrameIndex const& other) const { return _value < other._value; }
1✔
26
    bool operator<=(CameraFrameIndex const& other) const { return _value <= other._value; }
184✔
27
    bool operator>(CameraFrameIndex const& other) const { return _value > other._value; }
1✔
28
    bool operator>=(CameraFrameIndex const& other) const { return _value >= other._value; }
213✔
29
    
30
    // Arithmetic operations
31
    CameraFrameIndex operator+(int64_t offset) const { return CameraFrameIndex(_value + offset); }
2✔
32
    CameraFrameIndex operator-(int64_t offset) const { return CameraFrameIndex(_value - offset); }
2✔
33
    int64_t operator-(CameraFrameIndex const& other) const { return _value - other._value; }
2✔
34
    
35
private:
36
    int64_t _value;
37
};
38

39
/**
40
 * @brief Strong type for clock tick values
41
 * 
42
 * Represents raw clock ticks from acquisition hardware. Can be converted
43
 * to seconds if the sampling rate is known (stored in associated TimeFrame).
44
 * Multiple data streams using the same clock can be confidently synchronized.
45
 */
46
class ClockTicks {
47
public:
48
    explicit ClockTicks(int64_t value) : _value(value) {}
71,064✔
49
    
50
    [[nodiscard]] int64_t getValue() const { return _value; }
40✔
51
    
52
    // Comparison operators
53
    bool operator==(ClockTicks const& other) const { return _value == other._value; }
1✔
54
    bool operator!=(ClockTicks const& other) const { return _value != other._value; }
1✔
55
    bool operator<(ClockTicks const& other) const { return _value < other._value; }
1✔
56
    bool operator<=(ClockTicks const& other) const { return _value <= other._value; }
63,509✔
57
    bool operator>(ClockTicks const& other) const { return _value > other._value; }
1✔
58
    bool operator>=(ClockTicks const& other) const { return _value >= other._value; }
71,009✔
59
    
60
    // Arithmetic operations
61
    ClockTicks operator+(int64_t offset) const { return ClockTicks(_value + offset); }
1✔
62
    ClockTicks operator-(int64_t offset) const { return ClockTicks(_value - offset); }
1✔
63
    int64_t operator-(ClockTicks const& other) const { return _value - other._value; }
1✔
64
    
65
private:
66
    int64_t _value;
67
};
68

69
/**
70
 * @brief Strong type for time values in seconds
71
 * 
72
 * Represents absolute time in seconds. Can be converted to/from other
73
 * time coordinate systems when calibration information is available.
74
 */
75
class Seconds {
76
public:
77
    explicit Seconds(double value) : _value(value) {}
21✔
78
    
79
    [[nodiscard]] double getValue() const { return _value; }
17✔
80
    
81
    // Comparison operators
82
    bool operator==(Seconds const& other) const { return _value == other._value; }
1✔
83
    bool operator!=(Seconds const& other) const { return _value != other._value; }
1✔
84
    bool operator<(Seconds const& other) const { return _value < other._value; }
1✔
85
    bool operator<=(Seconds const& other) const { return _value <= other._value; }
2✔
86
    bool operator>(Seconds const& other) const { return _value > other._value; }
1✔
87
    bool operator>=(Seconds const& other) const { return _value >= other._value; }
2✔
88
    
89
    // Arithmetic operations
90
    Seconds operator+(double offset) const { return Seconds(_value + offset); }
1✔
91
    Seconds operator-(double offset) const { return Seconds(_value - offset); }
1✔
92
    double operator-(Seconds const& other) const { return _value - other._value; }
1✔
93
    
94
private:
95
    double _value;
96
};
97

98
/**
99
 * @brief Strong type for uncalibrated coordinate values
100
 * 
101
 * Represents time coordinate values that haven't been calibrated or
102
 * whose coordinate system is unknown. Requires explicit unsafe casting
103
 * to convert to other coordinate systems.
104
 * 
105
 * Use this type when processing data where the time coordinate system
106
 * is not important (e.g., algorithmic processing that preserves timing).
107
 */
108
class UncalibratedIndex {
109
public:
110
    explicit UncalibratedIndex(int64_t value) : _value(value) {}
18✔
111
    
112
    [[nodiscard]] int64_t getValue() const { return _value; }
12✔
113
    
114
    // Comparison operators
115
    bool operator==(UncalibratedIndex const& other) const { return _value == other._value; }
1✔
116
    bool operator!=(UncalibratedIndex const& other) const { return _value != other._value; }
1✔
117
    bool operator<(UncalibratedIndex const& other) const { return _value < other._value; }
1✔
118
    bool operator<=(UncalibratedIndex const& other) const { return _value <= other._value; }
2✔
119
    bool operator>(UncalibratedIndex const& other) const { return _value > other._value; }
1✔
120
    bool operator>=(UncalibratedIndex const& other) const { return _value >= other._value; }
2✔
121
    
122
    // Arithmetic operations
123
    UncalibratedIndex operator+(int64_t offset) const { return UncalibratedIndex(_value + offset); }
2✔
124
    UncalibratedIndex operator-(int64_t offset) const { return UncalibratedIndex(_value - offset); }
1✔
125
    int64_t operator-(UncalibratedIndex const& other) const { return _value - other._value; }
1✔
126
    
127
    /**
128
     * @brief Unsafe conversion to CameraFrameIndex
129
     * 
130
     * WARNING: This conversion assumes that the uncalibrated index
131
     * represents camera frame indices. Use only when you are certain
132
     * of the coordinate system.
133
     * 
134
     * @return CameraFrameIndex with the same numeric value
135
     */
136
    [[nodiscard]] CameraFrameIndex unsafeToCameraFrameIndex() const {
1✔
137
        return CameraFrameIndex(_value);
1✔
138
    }
139
    
140
    /**
141
     * @brief Unsafe conversion to ClockTicks
142
     * 
143
     * WARNING: This conversion assumes that the uncalibrated index
144
     * represents clock tick values. Use only when you are certain
145
     * of the coordinate system.
146
     * 
147
     * @return ClockTicks with the same numeric value
148
     */
149
    [[nodiscard]] ClockTicks unsafeToClockTicks() const {
1✔
150
        return ClockTicks(_value);
1✔
151
    }
152
    
153
private:
154
    int64_t _value;
155
};
156

157
/**
158
 * @brief Strong type for indices into data arrays within time series objects
159
 * 
160
 * Represents direct indices into the _data vector of time series classes.
161
 * This is distinct from TimeFrameIndex (which indexes into time coordinate space)
162
 * and from time coordinates themselves. Use this when you need to access
163
 * data by its position in the storage array, regardless of time semantics.
164
 */
165
class DataArrayIndex {
166
public:
167
    explicit DataArrayIndex(size_t value) : _value(value) {}
71,433✔
168
    
169
    [[nodiscard]] size_t getValue() const { return _value; }
142,727✔
170
    
171
    // Comparison operators
172
    bool operator==(DataArrayIndex const& other) const { return _value == other._value; }
173
    bool operator!=(DataArrayIndex const& other) const { return _value != other._value; }
UNCOV
174
    bool operator<(DataArrayIndex const& other) const { return _value < other._value; }
×
175
    bool operator<=(DataArrayIndex const& other) const { return _value <= other._value; }
176
    bool operator>(DataArrayIndex const& other) const { return _value > other._value; }
177
    bool operator>=(DataArrayIndex const& other) const { return _value >= other._value; }
178
    
179
    // Arithmetic operations
180
    DataArrayIndex operator+(size_t offset) const { return DataArrayIndex(_value + offset); }
181
    DataArrayIndex operator-(size_t offset) const { return DataArrayIndex(_value - offset); }
UNCOV
182
    size_t operator-(DataArrayIndex const& other) const { return _value - other._value; }
×
183
    
184
    // Pre and post increment/decrement for iteration
UNCOV
185
    DataArrayIndex& operator++() { ++_value; return *this; }
×
186
    DataArrayIndex operator++(int) { DataArrayIndex temp(*this); ++_value; return temp; }
187
    DataArrayIndex& operator--() { --_value; return *this; }
188
    DataArrayIndex operator--(int) { DataArrayIndex temp(*this); --_value; return temp; }
189
    
190
private:
191
    size_t _value;
192
};
193

194
/**
195
 * @brief Variant type that can hold any of the strong time coordinate types
196
 * 
197
 * Useful for APIs that need to work with multiple coordinate systems
198
 * or for storing time coordinates whose type is determined at runtime.
199
 */
200
using TimeCoordinate = std::variant<CameraFrameIndex, ClockTicks, Seconds, UncalibratedIndex>;
201

202
/**
203
 * @brief Helper function to extract the numeric value from any TimeCoordinate
204
 * 
205
 * @param coord The time coordinate variant
206
 * @return The underlying numeric value (int64_t for integer types, double for Seconds)
207
 */
208
template<typename ReturnType = int64_t>
209
[[nodiscard]] ReturnType getTimeValue(TimeCoordinate const& coord) {
10✔
210
    return std::visit([](auto const& value) -> ReturnType {
20✔
211
        if constexpr (std::is_same_v<decltype(value), Seconds const&>) {
212
            if constexpr (std::is_same_v<ReturnType, double>) {
213
                return value.getValue();
2✔
214
            } else {
215
                return static_cast<ReturnType>(value.getValue());
2✔
216
            }
217
        } else {
218
            if constexpr (std::is_same_v<ReturnType, double>) {
219
                return static_cast<double>(value.getValue());
3✔
220
            } else {
221
                return static_cast<ReturnType>(value.getValue());
3✔
222
            }
223
        }
224
    }, coord);
20✔
225
}
226

227
#endif // STRONG_TIME_TYPES_HPP 
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc