GCC Code Coverage Report


Directory: ./
File: Os/Delegate.hpp
Date: 2026-09-03 21:13:48
Exec Total Coverage
Lines: 12 12 100.0%
Functions: 31 33 93.9%
Branches: 5 11 45.5%

Line Branch Exec Source
1 // ======================================================================
2 // \title Os/Delegate.hpp
3 // \brief helper functions to ease correct getDelegate implementations
4 // ======================================================================
5 #include <new>
6 #include <type_traits>
7 #include "Fw/Types/Assert.hpp"
8 #include "Os/Os.hpp"
9 #ifndef OS_DELEGATE_HPP_
10 #define OS_DELEGATE_HPP_
11 namespace Os {
12 namespace Delegate {
13
14 //! \brief Make a delegate of type Interface using Implementation without copy-constructor support (generic function)
15 //!
16 //! This function is a generic implementation of the `getDelegate` functions provided for each function within Os. This
17 //! is templated over two types: Interface (e.g. TaskInterface) the interface the delegate supports, and Implementation
18 //! the implementation of the interface. This function takes care of the critical requirements of the getDelegate
19 //! function:
20 //! 1. Ensure Implementation is derived from Interface
21 //! 2. Ensure Implementation fits within FW_HANDLE_MAX_SIZE
22 //! 3. Ensure Implementation alignment fits within FW_HANDLE_ALIGNMENT
23 //! 4. Performs the correct placement new for normal constructors
24 //! 5. Ensure the returned pointer is not nullptr
25 //!
26 //! Implementors of a `getDelegate` function may use this function by calling it and returning the result.
27 //!
28 //! > Neither Interface nor Implementation is allowed to support copy-constructors
29 //!
30 //! Example: TaskInterface getDelegate (Without Copy-Constructor)
31 //!
32 //! ```c++
33 //! #include "Os/Delegate.hpp"
34 //!
35 //! namespace Os {
36 //! TaskInterface* TaskInterface::getDelegate(HandleStorage& aligned_new_memory) {
37 //! return Os::Delegate::makeDelegate<TaskInterface, Os::Posix::Task::PosixTask>(aligned_new_memory);
38 //! }
39 //! }
40 //! ```
41 //! \tparam Interface: interface the delegate supports (e.g. TaskInterface)
42 //! \tparam Implementation: implementation class of the delegate (e.g. PosixTask)
43 //! \param aligned_new_memory: memory to be filled via placement new call
44 //! \return pointer to implementation result of placement new
45 template <class Interface, class Implementation, class StorageType>
46 21991 inline Interface* makeDelegate(StorageType& aligned_new_memory) {
47 // Ensure prerequisites before performing placement new
48 static_assert(std::is_base_of<Interface, Implementation>::value, "Implementation must derive from Interface");
49 static_assert(sizeof(Implementation) <= sizeof(StorageType), "Handle size not large enough");
50 static_assert((FW_HANDLE_ALIGNMENT % alignof(Implementation)) == 0, "Handle alignment invalid");
51 // Placement new the object and ensure non-null result
52
1/3
✓ Branch 3 taken 4841 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
21991 Implementation* interface = new (aligned_new_memory) Implementation;
53 21991 FW_ASSERT(interface != nullptr);
54 21991 return interface;
55 }
56
57 //! \brief Make a delegate of type Interface using Implementation with copy-constructor support (generic function)
58 //!
59 //! This function is a generic implementation of the `getDelegate` functions provided for each function within Os. This
60 //! is templated over two types: Interface (e.g. TaskInterface) the interface the delegate supports, and Implementation
61 //! the implementation of the interface. This function takes care of the critical requirements of the getDelegate
62 //! function:
63 //! 1. Ensure Implementation is derived from Interface
64 //! 2. Ensure Implementation fits within FW_HANDLE_MAX_SIZE
65 //! 3. Ensure Implementation alignment fits within FW_HANDLE_ALIGNMENT
66 //! 4. Performs the correct placement new for normal and copy constructors
67 //! 5. Ensure the returned pointer is not nullptr
68 //!
69 //! Implementors of a `getDelegate` function may use this function by calling it and returning the result.
70 //!
71 //! Example: FileInterface getDelegate Supporting Copy-Constructor
72 //!
73 //! ```c++
74 //! #include "Os/Delegate.hpp"
75 //!
76 //! namespace Os {
77 //! FileInterface* FileInterface::getDelegate(HandleStorage& aligned_new_memory, const FileInterface* to_copy) {
78 //! return Os::Delegate::makeDelegate<FileInterface, Os::Posix::File::PosixFile>(aligned_new_memory, to_copy);
79 //! }
80 //! }
81 //! ```
82 //! \tparam Interface: interface the delegate supports (e.g. FileInterface)
83 //! \tparam Implementation: implementation class of the delegate (e.g. PosixFile)
84 //! \param aligned_new_memory: memory to be filled via placement new call
85 //! \return pointer to implementation result of placement new
86 //! \param to_copy: pointer to Interface to be copied by copy constructor
87 //! \return pointer to implementation result of placement new
88 template <class Interface, class Implementation, class StorageType>
89 147340 inline Interface* makeDelegate(StorageType& aligned_new_memory, const Interface* to_copy) {
90 147340 const Implementation* copy_me = reinterpret_cast<const Implementation*>(to_copy);
91 // Ensure prerequisites before performing placement new
92 static_assert(std::is_base_of<Interface, Implementation>::value, "Implementation must derive from Interface");
93 static_assert(sizeof(Implementation) <= sizeof(aligned_new_memory), "Handle size not large enough");
94 static_assert((FW_HANDLE_ALIGNMENT % alignof(Implementation)) == 0, "Handle alignment invalid");
95 // Placement new the object and ensure non-null result
96 147340 Implementation* interface = nullptr;
97
2/2
✓ Branch 0 taken 146187 times.
✓ Branch 1 taken 1153 times.
147340 if (to_copy == nullptr) {
98
1/3
✓ Branch 3 taken 102927 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
146187 interface = new (aligned_new_memory) Implementation;
99 } else {
100
1/3
✓ Branch 4 taken 369 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1153 interface = new (aligned_new_memory) Implementation(*copy_me);
101 }
102 147340 FW_ASSERT(interface != nullptr);
103 147340 return interface;
104 }
105 } // namespace Delegate
106 } // namespace Os
107 #endif
108