GCC Code Coverage Report


Directory: Fw/Types/
File: PolyType.cpp
Date: 2026-09-03 21:15:04
Exec Total Coverage
Lines: 168 438 38.4%
Functions: 39 74 52.7%
Branches: 21 173 12.1%

Line Branch Exec Source
1 #include <Fw/Types/Assert.hpp>
2 #include <Fw/Types/ExternalString.hpp>
3 #include <Fw/Types/PolyType.hpp>
4
5 namespace Fw {
6
7 // U8 methods
8
9 PolyType::PolyType() {
10 this->m_dataType = TYPE_NOTYPE;
11 }
12
13 1 PolyType::PolyType(U8 val) {
14 1 this->m_dataType = TYPE_U8;
15 1 this->m_val.u8Val = val;
16 1 }
17
18 4 PolyType::operator U8() const {
19 4 FW_ASSERT(TYPE_U8 == this->m_dataType);
20 4 return this->m_val.u8Val;
21 }
22
23 void PolyType::get(U8& val) const {
24 FW_ASSERT(TYPE_U8 == this->m_dataType);
25 val = this->m_val.u8Val;
26 }
27
28 bool PolyType::isU8() const {
29 return (TYPE_U8 == this->m_dataType);
30 }
31
32 1 PolyType& PolyType::operator=(U8 other) {
33 1 this->m_dataType = TYPE_U8;
34 1 this->m_val.u8Val = other;
35 1 return *this;
36 }
37
38 // I8 methods
39
40 1 PolyType::PolyType(I8 val) {
41 1 this->m_dataType = TYPE_I8;
42 1 this->m_val.i8Val = val;
43 1 }
44
45 3 PolyType::operator I8() const {
46 3 FW_ASSERT(TYPE_I8 == this->m_dataType);
47 3 return this->m_val.i8Val;
48 }
49
50 void PolyType::get(I8& val) const {
51 FW_ASSERT(TYPE_I8 == this->m_dataType);
52 val = this->m_val.i8Val;
53 }
54
55 bool PolyType::isI8() const {
56 return (TYPE_I8 == this->m_dataType);
57 }
58
59 1 PolyType& PolyType::operator=(I8 other) {
60 1 this->m_dataType = TYPE_I8;
61 1 this->m_val.i8Val = other;
62 1 return *this;
63 }
64
65 #if FW_HAS_16_BIT
66
67 // U16 methods
68
69 1 PolyType::PolyType(U16 val) {
70 1 this->m_dataType = TYPE_U16;
71 1 this->m_val.u16Val = val;
72 1 }
73
74 3 PolyType::operator U16() const {
75 3 FW_ASSERT(TYPE_U16 == this->m_dataType);
76 3 return this->m_val.u16Val;
77 }
78
79 void PolyType::get(U16& val) const {
80 FW_ASSERT(TYPE_U16 == this->m_dataType);
81 val = this->m_val.u16Val;
82 }
83
84 bool PolyType::isU16() const {
85 return (TYPE_U16 == this->m_dataType);
86 }
87
88 1 PolyType& PolyType::operator=(U16 other) {
89 1 this->m_dataType = TYPE_U16;
90 1 this->m_val.u16Val = other;
91 1 return *this;
92 }
93
94 // I16 methods
95
96 1 PolyType::PolyType(I16 val) {
97 1 this->m_dataType = TYPE_I16;
98 1 this->m_val.i16Val = val;
99 1 }
100
101 3 PolyType::operator I16() const {
102 3 FW_ASSERT(TYPE_I16 == this->m_dataType);
103 3 return this->m_val.i16Val;
104 }
105
106 void PolyType::get(I16& val) const {
107 FW_ASSERT(TYPE_I16 == this->m_dataType);
108 val = this->m_val.i16Val;
109 }
110
111 bool PolyType::isI16() const {
112 return (TYPE_I16 == this->m_dataType);
113 }
114
115 1 PolyType& PolyType::operator=(I16 other) {
116 1 this->m_dataType = TYPE_I16;
117 1 this->m_val.i16Val = other;
118 1 return *this;
119 }
120
121 #endif
122
123 #if FW_HAS_32_BIT
124
125 // U32 methods
126
127 1 PolyType::PolyType(U32 val) {
128 1 this->m_dataType = TYPE_U32;
129 1 this->m_val.u32Val = val;
130 1 }
131
132 3 PolyType::operator U32() const {
133 3 FW_ASSERT(TYPE_U32 == this->m_dataType);
134 3 return this->m_val.u32Val;
135 }
136
137 void PolyType::get(U32& val) const {
138 FW_ASSERT(TYPE_U32 == this->m_dataType);
139 val = this->m_val.u32Val;
140 }
141
142 bool PolyType::isU32() const {
143 return (TYPE_U32 == this->m_dataType);
144 }
145
146 1 PolyType& PolyType::operator=(U32 other) {
147 1 this->m_dataType = TYPE_U32;
148 1 this->m_val.u32Val = other;
149 1 return *this;
150 }
151
152 // I32 methods
153
154 1 PolyType::PolyType(I32 val) {
155 1 this->m_dataType = TYPE_I32;
156 1 this->m_val.i32Val = val;
157 1 }
158
159 3 PolyType::operator I32() const {
160 3 FW_ASSERT(TYPE_I32 == this->m_dataType);
161 3 return this->m_val.i32Val;
162 }
163
164 void PolyType::get(I32& val) const {
165 FW_ASSERT(TYPE_I32 == this->m_dataType);
166 val = this->m_val.i32Val;
167 }
168
169 bool PolyType::isI32() const {
170 return (TYPE_I32 == this->m_dataType);
171 }
172
173 1 PolyType& PolyType::operator=(I32 other) {
174 1 this->m_dataType = TYPE_I32;
175 1 this->m_val.i32Val = other;
176 1 return *this;
177 }
178
179 #endif
180 #if FW_HAS_64_BIT
181
182 // U64 methods
183
184 1 PolyType::PolyType(U64 val) {
185 1 this->m_dataType = TYPE_U64;
186 1 this->m_val.u64Val = val;
187 1 }
188
189 3 PolyType::operator U64() const {
190 3 FW_ASSERT(TYPE_U64 == this->m_dataType);
191 3 return this->m_val.u64Val;
192 }
193
194 void PolyType::get(U64& val) const {
195 FW_ASSERT(TYPE_U64 == this->m_dataType);
196 val = this->m_val.u64Val;
197 }
198
199 bool PolyType::isU64() const {
200 return (TYPE_U64 == this->m_dataType);
201 }
202
203 1 PolyType& PolyType::operator=(U64 other) {
204 1 this->m_dataType = TYPE_U64;
205 1 this->m_val.u64Val = other;
206 1 return *this;
207 }
208
209 // I64 methods
210
211 1 PolyType::PolyType(I64 val) {
212 1 this->m_dataType = TYPE_I64;
213 1 this->m_val.i64Val = val;
214 1 }
215
216 3 PolyType::operator I64() const {
217 3 FW_ASSERT(TYPE_I64 == this->m_dataType);
218 3 return this->m_val.i64Val;
219 }
220
221 void PolyType::get(I64& val) const {
222 FW_ASSERT(TYPE_I64 == this->m_dataType);
223 val = this->m_val.i64Val;
224 }
225
226 bool PolyType::isI64() const {
227 return (TYPE_I64 == this->m_dataType);
228 }
229
230 1 PolyType& PolyType::operator=(I64 other) {
231 1 this->m_dataType = TYPE_I64;
232 1 this->m_val.i64Val = other;
233 1 return *this;
234 }
235
236 #endif
237
238 1 PolyType::PolyType(F64 val) {
239 1 this->m_dataType = TYPE_F64;
240 1 this->m_val.f64Val = val;
241 1 }
242
243 3 PolyType::operator F64() const {
244 3 FW_ASSERT(TYPE_F64 == this->m_dataType);
245 3 return this->m_val.f64Val;
246 }
247
248 void PolyType::get(F64& val) const {
249 FW_ASSERT(TYPE_F64 == this->m_dataType);
250 val = this->m_val.f64Val;
251 }
252
253 bool PolyType::isF64() const {
254 return (TYPE_F64 == this->m_dataType);
255 }
256
257 1 PolyType& PolyType::operator=(F64 other) {
258 1 this->m_dataType = TYPE_F64;
259 1 this->m_val.f64Val = other;
260 1 return *this;
261 }
262
263 1 PolyType::PolyType(F32 val) {
264 1 this->m_dataType = TYPE_F32;
265 1 this->m_val.f32Val = val;
266 1 }
267
268 3 PolyType::operator F32() const {
269 3 FW_ASSERT(TYPE_F32 == this->m_dataType);
270 3 return this->m_val.f32Val;
271 }
272
273 void PolyType::get(F32& val) const {
274 FW_ASSERT(TYPE_F32 == this->m_dataType);
275 val = this->m_val.f32Val;
276 }
277
278 bool PolyType::isF32() const {
279 return (TYPE_F32 == this->m_dataType);
280 }
281
282 1 PolyType& PolyType::operator=(F32 other) {
283 1 this->m_dataType = TYPE_F32;
284 1 this->m_val.f32Val = other;
285 1 return *this;
286 }
287
288 1 PolyType::PolyType(bool val) {
289 1 this->m_dataType = TYPE_BOOL;
290 1 this->m_val.boolVal = val;
291 1 }
292
293 3 PolyType::operator bool() const {
294 3 FW_ASSERT(TYPE_BOOL == this->m_dataType);
295
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 return this->m_val.boolVal;
296 }
297
298 void PolyType::get(bool& val) const {
299 FW_ASSERT(TYPE_BOOL == this->m_dataType);
300 val = this->m_val.boolVal;
301 }
302
303 bool PolyType::isBool() const {
304 return (TYPE_BOOL == this->m_dataType);
305 }
306
307 1 PolyType& PolyType::operator=(bool other) {
308 1 this->m_dataType = TYPE_BOOL;
309 1 this->m_val.boolVal = other;
310 1 return *this;
311 }
312
313 1 PolyType::PolyType(void* val) {
314 1 this->m_dataType = TYPE_PTR;
315 1 this->m_val.ptrVal = val;
316 1 }
317
318 3 PolyType::operator void*() const {
319 3 FW_ASSERT(TYPE_PTR == this->m_dataType);
320 3 return this->m_val.ptrVal;
321 }
322
323 void PolyType::get(void*& val) const {
324 FW_ASSERT(TYPE_PTR == this->m_dataType);
325 val = this->m_val.ptrVal;
326 }
327
328 bool PolyType::isPtr() const {
329 return (TYPE_PTR == this->m_dataType);
330 }
331
332 1 PolyType& PolyType::operator=(void* other) {
333 1 this->m_dataType = TYPE_PTR;
334 1 this->m_val.ptrVal = other;
335 1 return *this;
336 }
337
338 PolyType::PolyType(const PolyType& original)
339 : Fw::Serializable(), m_dataType(original.m_dataType), m_val(original.m_val) {}
340
341 24 PolyType::~PolyType() = default;
342
343 PolyType& PolyType::operator=(const PolyType& src) {
344 this->m_dataType = src.m_dataType;
345 this->m_val = src.m_val;
346 return *this;
347 }
348
349 bool PolyType::operator!=(const PolyType& other) const {
350 return !operator==(other);
351 }
352
353 bool PolyType::operator==(const PolyType& other) const {
354 // if type doesn't match, not equal
355 if (this->m_dataType != other.m_dataType) {
356 return false;
357 } else {
358 // check based on type
359 bool valIsEqual = false;
360 switch (this->m_dataType) {
361 case TYPE_U8:
362 valIsEqual = (this->m_val.u8Val == other.m_val.u8Val);
363 break;
364 case TYPE_I8:
365 valIsEqual = (this->m_val.i8Val == other.m_val.i8Val);
366 break;
367 #if FW_HAS_16_BIT
368 case TYPE_U16:
369 valIsEqual = (this->m_val.u16Val == other.m_val.u16Val);
370 break;
371 case TYPE_I16:
372 valIsEqual = (this->m_val.i16Val == other.m_val.i16Val);
373 break;
374 #endif
375 #if FW_HAS_32_BIT
376 case TYPE_U32:
377 valIsEqual = (this->m_val.u32Val == other.m_val.u32Val);
378 break;
379 case TYPE_I32:
380 valIsEqual = (this->m_val.i32Val == other.m_val.i32Val);
381 break;
382 #endif
383 #if FW_HAS_64_BIT
384 case TYPE_U64:
385 valIsEqual = (this->m_val.u64Val == other.m_val.u64Val);
386 break;
387 case TYPE_I64:
388 valIsEqual = (this->m_val.i64Val == other.m_val.i64Val);
389 break;
390 #endif
391 case TYPE_BOOL:
392 valIsEqual = (this->m_val.boolVal == other.m_val.boolVal);
393 break;
394 case TYPE_PTR:
395 valIsEqual = (this->m_val.ptrVal == other.m_val.ptrVal);
396 break;
397 case TYPE_F64: // fall through, shouldn't test floating point
398 case TYPE_F32: // fall through, shouldn't test floating point
399 case TYPE_NOTYPE:
400 valIsEqual = false;
401 break;
402 default:
403 FW_ASSERT(false, static_cast<FwAssertArgType>(this->m_dataType));
404 return false; // for compiler
405 }
406 return valIsEqual;
407 }
408 }
409
410 bool PolyType::operator<(const PolyType& other) const {
411 // if type doesn't match, not equal
412 if (this->m_dataType != other.m_dataType) {
413 return false;
414 } else {
415 // check based on type
416 bool result = false;
417 switch (this->m_dataType) {
418 case TYPE_U8:
419 result = (this->m_val.u8Val < other.m_val.u8Val);
420 break;
421 case TYPE_I8:
422 result = (this->m_val.i8Val < other.m_val.i8Val);
423 break;
424 #if FW_HAS_16_BIT
425 case TYPE_U16:
426 result = (this->m_val.u16Val < other.m_val.u16Val);
427 break;
428 case TYPE_I16:
429 result = (this->m_val.i16Val < other.m_val.i16Val);
430 break;
431 #endif
432 #if FW_HAS_32_BIT
433 case TYPE_U32:
434 result = (this->m_val.u32Val < other.m_val.u32Val);
435 break;
436 case TYPE_I32:
437 result = (this->m_val.i32Val < other.m_val.i32Val);
438 break;
439 #endif
440 #if FW_HAS_64_BIT
441 case TYPE_U64:
442 result = (this->m_val.u64Val < other.m_val.u64Val);
443 break;
444 case TYPE_I64:
445 result = (this->m_val.i64Val < other.m_val.i64Val);
446 break;
447 #endif
448 case TYPE_F64:
449 result = (this->m_val.f64Val < other.m_val.f64Val);
450 break;
451 case TYPE_F32:
452 result = (this->m_val.f32Val < other.m_val.f32Val);
453 break;
454 case TYPE_PTR:
455 result = (this->m_val.ptrVal < other.m_val.ptrVal);
456 break;
457 case TYPE_BOOL: // fall through, shouldn't test bool
458 case TYPE_NOTYPE:
459 result = false;
460 break;
461 default:
462 FW_ASSERT(false, static_cast<FwAssertArgType>(this->m_dataType));
463 return false; // for compiler
464 }
465 return result;
466 }
467 }
468
469 bool PolyType::operator>(const PolyType& other) const {
470 return other.operator<(*this);
471 }
472
473 bool PolyType::operator>=(const PolyType& other) const {
474 return (this->operator>(other)) || (this->operator==(other));
475 }
476
477 bool PolyType::operator<=(const PolyType& other) const {
478 return (this->operator<(other)) || (this->operator==(other));
479 }
480
481 SerializeStatus PolyType::serializeTo(SerialBufferBase& buffer, Fw::Endianness mode) const {
482 // store type
483 SerializeStatus stat = buffer.serializeFrom(static_cast<FwEnumStoreType>(this->m_dataType), mode);
484 if (stat != FW_SERIALIZE_OK) {
485 return stat;
486 }
487
488 // switch on type
489 switch (this->m_dataType) {
490 case TYPE_U8:
491 stat = buffer.serializeFrom(this->m_val.u8Val, mode);
492 break;
493 case TYPE_I8:
494 stat = buffer.serializeFrom(this->m_val.i8Val, mode);
495 break;
496 #if FW_HAS_16_BIT
497 case TYPE_U16:
498 stat = buffer.serializeFrom(this->m_val.u16Val, mode);
499 break;
500 case TYPE_I16:
501 stat = buffer.serializeFrom(this->m_val.i16Val, mode);
502 break;
503 #endif
504 #if FW_HAS_32_BIT
505 case TYPE_U32:
506 stat = buffer.serializeFrom(this->m_val.u32Val, mode);
507 break;
508 case TYPE_I32:
509 stat = buffer.serializeFrom(this->m_val.i32Val, mode);
510 break;
511 #endif
512 #if FW_HAS_64_BIT
513 case TYPE_U64:
514 stat = buffer.serializeFrom(this->m_val.u64Val, mode);
515 break;
516 case TYPE_I64:
517 stat = buffer.serializeFrom(this->m_val.i64Val, mode);
518 break;
519 #endif
520 case TYPE_F64:
521 stat = buffer.serializeFrom(this->m_val.f64Val, mode);
522 break;
523 case TYPE_F32:
524 stat = buffer.serializeFrom(this->m_val.f32Val, mode);
525 break;
526 case TYPE_BOOL:
527 stat = buffer.serializeFrom(this->m_val.boolVal, mode);
528 break;
529 case TYPE_PTR:
530 stat = buffer.serializeFrom(this->m_val.ptrVal, mode);
531 break;
532 default:
533 stat = FW_SERIALIZE_FORMAT_ERROR;
534 break;
535 }
536
537 return stat;
538 }
539
540 SerializeStatus PolyType::deserializeFrom(SerialBufferBase& buffer, Fw::Endianness mode) {
541 // get type
542 FwEnumStoreType des;
543 SerializeStatus stat = buffer.deserializeTo(des, mode);
544
545 if (stat != FW_SERIALIZE_OK) {
546 return stat;
547 } else {
548 this->m_dataType = static_cast<Type>(des);
549 // switch on type
550 switch (this->m_dataType) {
551 case TYPE_U8:
552 return buffer.deserializeTo(this->m_val.u8Val, mode);
553 case TYPE_I8:
554 return buffer.deserializeTo(this->m_val.i8Val, mode);
555 #if FW_HAS_16_BIT
556 case TYPE_U16:
557 return buffer.deserializeTo(this->m_val.u16Val, mode);
558 case TYPE_I16:
559 return buffer.deserializeTo(this->m_val.i16Val, mode);
560 #endif
561 #if FW_HAS_32_BIT
562 case TYPE_U32:
563 return buffer.deserializeTo(this->m_val.u32Val, mode);
564 case TYPE_I32:
565 return buffer.deserializeTo(this->m_val.i32Val, mode);
566 #endif
567 #if FW_HAS_64_BIT
568 case TYPE_U64:
569 return buffer.deserializeTo(this->m_val.u64Val, mode);
570 case TYPE_I64:
571 return buffer.deserializeTo(this->m_val.i64Val, mode);
572 #endif
573 case TYPE_F64:
574 return buffer.deserializeTo(this->m_val.f64Val, mode);
575 case TYPE_F32:
576 return buffer.deserializeTo(this->m_val.f32Val, mode);
577 case TYPE_BOOL:
578 return buffer.deserializeTo(this->m_val.boolVal, mode);
579 case TYPE_PTR:
580 return buffer.deserializeTo(this->m_val.ptrVal, mode);
581 default:
582 return FW_DESERIALIZE_FORMAT_ERROR;
583 }
584 }
585 }
586
587 #if FW_SERIALIZABLE_TO_STRING || BUILD_UT
588
589 8 void PolyType::toString(StringBase& dest) const {
590 8 this->toString(dest, false);
591 8 }
592
593 8 void PolyType::toString(StringBase& dest, bool append) const {
594 8 char format[21]; // U64 max fits into 20 decimal digits + 1 null terminator
595
1/1
✓ Branch 2 taken 8 times.
8 Fw::ExternalString external(format, sizeof format);
596
9/15
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
8 switch (this->m_dataType) {
597 1 case TYPE_U8:
598
1/1
✓ Branch 6 taken 1 times.
1 (void)external.format("%" PRIu8 " ", this->m_val.u8Val);
599 1 break;
600 1 case TYPE_I8:
601
1/1
✓ Branch 6 taken 1 times.
1 (void)external.format("%" PRId8 " ", this->m_val.i8Val);
602 1 break;
603 #if FW_HAS_16_BIT
604 1 case TYPE_U16:
605
1/1
✓ Branch 6 taken 1 times.
1 (void)external.format("%" PRIu16 " ", this->m_val.u16Val);
606 1 break;
607 1 case TYPE_I16:
608
1/1
✓ Branch 6 taken 1 times.
1 (void)external.format("%" PRId16 " ", this->m_val.i16Val);
609 1 break;
610 #endif
611 #if FW_HAS_32_BIT
612 1 case TYPE_U32:
613
1/1
✓ Branch 6 taken 1 times.
1 (void)external.format("%" PRIu32 " ", this->m_val.u32Val);
614 1 break;
615 1 case TYPE_I32:
616
1/1
✓ Branch 6 taken 1 times.
1 (void)external.format("%" PRId32 " ", this->m_val.i32Val);
617 1 break;
618 #endif
619 #if FW_HAS_64_BIT
620 1 case TYPE_U64:
621
1/1
✓ Branch 6 taken 1 times.
1 (void)external.format("%" PRIu64 " ", this->m_val.u64Val);
622 1 break;
623 1 case TYPE_I64:
624
1/1
✓ Branch 6 taken 1 times.
1 (void)external.format("%" PRId64 " ", this->m_val.i64Val);
625 1 break;
626 #endif
627 case TYPE_F64:
628 (void)external.format("%g ", this->m_val.f64Val);
629 break;
630 case TYPE_F32:
631 (void)external.format("%g ", static_cast<F64>(this->m_val.f32Val));
632 break;
633 case TYPE_BOOL:
634 (void)external.format("%s ", this->m_val.boolVal ? "T" : "F");
635 break;
636 case TYPE_PTR:
637 (void)external.format("%p ", this->m_val.ptrVal);
638 break;
639 default:
640 (void)external.format("%s ", "NT");
641 break;
642 }
643 // Every case above must have produced a non-empty representation
644 8 FW_ASSERT(external.length() > 0, static_cast<FwAssertArgType>(this->m_dataType));
645
646
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (append) {
647 dest += external;
648 } else {
649
1/1
✓ Branch 4 taken 8 times.
8 dest = static_cast<const StringBase&>(external);
650 }
651 16 }
652
653 #endif
654 } // namespace Fw
655