GCC Code Coverage Report


Directory: ./
File: Os/Delegate.hpp
Date: 2026-09-03 22:12:29
Exec Total Coverage
Lines: 11 12 91.7%
Functions: 9 21 42.9%
Branches: 3 11 27.3%

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 190 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 2 taken 30 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
190 Implementation* interface = new (aligned_new_memory) Implementation;
53 190 FW_ASSERT(interface != nullptr);
54 190 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 1754 inline Interface* makeDelegate(StorageType& aligned_new_memory, const Interface* to_copy) {
90 1754 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 1754 Implementation* interface = nullptr;
97
1/2
✓ Branch 0 taken 1766 times.
✗ Branch 1 not taken.
1754 if (to_copy == nullptr) {
98
1/3
✓ Branch 2 taken 822 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1766 interface = new (aligned_new_memory) Implementation;
99 } else {
100 interface = new (aligned_new_memory) Implementation(*copy_me);
101 }
102 1769 FW_ASSERT(interface != nullptr);
103 1769 return interface;
104 }
105 } // namespace Delegate
106 } // namespace Os
107 #endif
108