Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * @file lib.Align.hpp | ||
3 | * @author Sergey Baigudin, sergey@baigudin.software | ||
4 | * @copyright 2016-2022, Sergey Baigudin, Baigudin Software | ||
5 | */ | ||
6 | #ifndef LIB_ALIGN_HPP_ | ||
7 | #define LIB_ALIGN_HPP_ | ||
8 | |||
9 | #include "lib.ObjectAllocator.hpp" | ||
10 | |||
11 | namespace eoos | ||
12 | { | ||
13 | namespace lib | ||
14 | { | ||
15 | |||
16 | /** | ||
17 | * @class Align<T,S,A> | ||
18 | * @brief Alignment of fundamental types to byte boundary of memory. | ||
19 | * | ||
20 | * MISRA C++ NOTE: Any signed underlying types shall not be used | ||
21 | * for not violating the 5-0-21 MISRA C++:2008 Rule. | ||
22 | * | ||
23 | * @tparam T Type of aligning data. | ||
24 | * @tparam S Size of aligning data type. | ||
25 | * @tparam A Heap memory allocator class. | ||
26 | */ | ||
27 | template <typename T, size_t S = sizeof(T), class A = Allocator> | ||
28 | class Align : public ObjectAllocator<A> | ||
29 | { | ||
30 | |||
31 | public: | ||
32 | |||
33 | /** | ||
34 | * @brief Constructor. | ||
35 | */ | ||
36 | 20 | Align() | |
37 | : ObjectAllocator<A>() { | ||
38 | 20 | } | |
39 | |||
40 | /** | ||
41 | * @brief Constructor. | ||
42 | * | ||
43 | * @note A passed value is copied to an internal data structure | ||
44 | * so that the value might be invalidated after the function called. | ||
45 | * | ||
46 | * @param value A data value. | ||
47 | */ | ||
48 | 52 | Align(T const& value) | |
49 | : ObjectAllocator<A>() { | ||
50 | 52 | assignment(value); | |
51 | 52 | } | |
52 | |||
53 | /** | ||
54 | * @brief Copy constructor. | ||
55 | * | ||
56 | * @param obj A source object. | ||
57 | */ | ||
58 | 2 | Align(Align const& obj) ///< SCA MISRA-C++:2008 Justified Rule 12-8-1 | |
59 | : ObjectAllocator<A>(obj) { | ||
60 | 2 | copy(obj); | |
61 | 2 | } | |
62 | |||
63 | /** | ||
64 | * @brief Destructor. | ||
65 | */ | ||
66 | 76 | ~Align() {} | |
67 | |||
68 | /** | ||
69 | * @brief Assignment operator. | ||
70 | * | ||
71 | * @note A passed value is copied to an internal data structure | ||
72 | * so that the value might be invalidated after the function called. | ||
73 | * | ||
74 | * @param value A source data value. | ||
75 | * @return Reference to this object. | ||
76 | */ | ||
77 | 1 | Align& operator=(T const& value) | |
78 | { | ||
79 | 1 | assignment(value); | |
80 | 1 | return *this; | |
81 | } | ||
82 | |||
83 | /** | ||
84 | * @brief Assignment operator. | ||
85 | * | ||
86 | * @param obj A source object. | ||
87 | * @return Reference to this object. | ||
88 | */ | ||
89 | 1 | Align& operator=(Align const& obj) | |
90 | { | ||
91 | 1 | copy(obj); | |
92 | 1 | return *this; | |
93 | } | ||
94 | |||
95 | /** | ||
96 | * @brief Pre-increment operator. | ||
97 | * | ||
98 | * @param obj A source object. | ||
99 | * @return Reference to this object. | ||
100 | */ | ||
101 | 1 | Align& operator++() | |
102 | { | ||
103 | 1 | T val( typecast() ); | |
104 | 1 | val += 1; | |
105 | 1 | assignment(val); | |
106 | 1 | return *this; | |
107 | } | ||
108 | |||
109 | /** | ||
110 | * @brief Pre-decrement operator. | ||
111 | * | ||
112 | * @param obj A source object. | ||
113 | * @return Reference to this object. | ||
114 | */ | ||
115 | 1 | Align& operator--() | |
116 | { | ||
117 | 1 | T val( typecast() ); | |
118 | 1 | val -= 1; | |
119 | 1 | assignment(val); | |
120 | 1 | return *this; | |
121 | } | ||
122 | |||
123 | /** | ||
124 | * @brief Post-increment operator. | ||
125 | * | ||
126 | * @return This object. | ||
127 | */ | ||
128 | 1 | Align operator++(int) ///< SCA MISRA-C++:2008 Justified Rule 3-9-2 | |
129 | { | ||
130 | 1 | T val( typecast() ); | |
131 | 1 | val += 1; | |
132 | 1 | assignment(val); | |
133 | 1 | return *this; | |
134 | } | ||
135 | |||
136 | /** | ||
137 | * @brief Post-decrement operator. | ||
138 | * | ||
139 | * @return This object. | ||
140 | */ | ||
141 | 1 | Align operator--(int) ///< SCA MISRA-C++:2008 Justified Rule 3-9-2 | |
142 | { | ||
143 | 1 | T val( typecast() ); | |
144 | 1 | val -= 1; | |
145 | 1 | assignment(val); | |
146 | 1 | return *this; | |
147 | } | ||
148 | |||
149 | /** | ||
150 | * @brief Casts to the template data type. | ||
151 | * | ||
152 | * @return A data value. | ||
153 | */ | ||
154 | 48 | operator T() const | |
155 | { | ||
156 | 48 | return typecast(); | |
157 | } | ||
158 | |||
159 | private: | ||
160 | |||
161 | /** | ||
162 | * @brief Compares a type based value with this class. | ||
163 | * | ||
164 | * @param val A source value. | ||
165 | * @return True if this object value equals to a passed value. | ||
166 | */ | ||
167 | bool_t equal(T const& value) const | ||
168 | { | ||
169 | Align<T,S,A> obj(value); | ||
170 | return equal(obj); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * @brief Compares an object of this class type with this class. | ||
175 | * | ||
176 | * @param obj A source object. | ||
177 | * @return True if this object value equals to a passed object value. | ||
178 | */ | ||
179 | 4 | bool_t equal(Align const& obj) const | |
180 | { | ||
181 | 4 | bool_t res( true ); | |
182 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
|
12 | for(size_t i(0U); i<S; i++) |
183 | { | ||
184 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
|
10 | if( val_[i] != obj.val_[i] ) |
185 | { | ||
186 | 2 | res = false; | |
187 | 2 | break; | |
188 | } | ||
189 | } | ||
190 | 4 | return res; | |
191 | } | ||
192 | |||
193 | /** | ||
194 | * @brief Assigns given value to self data. | ||
195 | * | ||
196 | * @param value Source data value. | ||
197 | */ | ||
198 | 62 | void assignment(T const& value) ///< SCA MISRA-C++:2008 Defected Rule 9-3-3 | |
199 | { | ||
200 |
2/2✓ Branch 0 taken 116 times.
✓ Branch 1 taken 31 times.
|
294 | for(size_t i(0U); i<S; i++) |
201 | { | ||
202 | 232 | T const v( value >> (8U * i) ); ///< SCA MISRA-C++:2008 Justified Rule 5-0-21 | |
203 | 232 | val_[i] = static_cast<ucell_t>(v); | |
204 | } | ||
205 | 62 | } | |
206 | |||
207 | /** | ||
208 | * @brief Copies given object to self data. | ||
209 | * | ||
210 | * @param obj Reference to source object. | ||
211 | */ | ||
212 | 3 | void copy(Align const& obj) ///< SCA MISRA-C++:2008 Defected Rule 9-3-3 | |
213 | { | ||
214 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3 times.
|
15 | for(size_t i(0U); i<S; i++) |
215 | { | ||
216 | 12 | val_[i] = obj.val_[i]; | |
217 | } | ||
218 | 3 | } | |
219 | |||
220 | /** | ||
221 | * @brief Returns conversed data to type of aligning data. | ||
222 | * | ||
223 | * @return Conversed data. | ||
224 | */ | ||
225 | 56 | T typecast() const | |
226 | { | ||
227 | 56 | int32_t const max( static_cast<int32_t>(S) - 1 ); | |
228 | 56 | T r( static_cast<T>(0) ); | |
229 |
2/2✓ Branch 0 taken 104 times.
✓ Branch 1 taken 28 times.
|
264 | for(int32_t i(max); i>=0; i--) |
230 | { | ||
231 | 208 | r = r << 8U; ///< SCA MISRA-C++:2008 Justified Rule 5-0-21 | |
232 | 208 | r = r | static_cast<T>(val_[i]); ///< SCA MISRA-C++:2008 Justified Rule 5-0-21 | |
233 | } | ||
234 | 56 | return r; | |
235 | } | ||
236 | |||
237 | /** | ||
238 | * @brief Array of data bytes. | ||
239 | */ | ||
240 | ucell_t val_[S]; | ||
241 | |||
242 | template <typename T0, size_t S0, class A0> friend bool_t operator==(Align<T0,S0,A0> const&, Align<T0,S0,A0> const&); | ||
243 | template <typename T0, size_t S0, class A0> friend bool_t operator!=(Align<T0,S0,A0> const&, Align<T0,S0,A0> const&); | ||
244 | }; | ||
245 | |||
246 | /** | ||
247 | * @brief Comparison operator to equal. | ||
248 | * | ||
249 | * @param obj1 Reference to object. | ||
250 | * @param obj2 Reference to object. | ||
251 | * @return True if objects are equal. | ||
252 | */ | ||
253 | template <typename T, size_t S, class A> | ||
254 | 2 | inline bool_t operator==(Align<T,S,A> const& obj1, Align<T,S,A> const& obj2) | |
255 | { | ||
256 | 2 | bool_t const res( obj1.equal(obj2) ); | |
257 | 2 | return res; | |
258 | } | ||
259 | |||
260 | /** | ||
261 | * @brief Comparison operator to unequal. | ||
262 | * | ||
263 | * @param obj1 Reference to object. | ||
264 | * @param obj2 Reference to object. | ||
265 | * @return True if objects are not equal. | ||
266 | */ | ||
267 | template <typename T, size_t S, class A> | ||
268 | 2 | inline bool_t operator!=(Align<T,S,A> const& obj1, Align<T,S,A> const& obj2) | |
269 | { | ||
270 | 2 | bool_t const res( obj1.equal(obj2) ); | |
271 | 2 | return !res; | |
272 | } | ||
273 | |||
274 | } // namespace lib | ||
275 | } // namespace eoos | ||
276 | #endif // LIB_ALIGN_HPP_ | ||
277 |