test/zserio/TraitsTest.cpp
Line | Count | Source |
1 | | #include <memory> |
2 | | #include <vector> |
3 | | |
4 | | #include "gtest/gtest.h" |
5 | | #include "zserio/AllocatorPropagatingCopy.h" |
6 | | #include "zserio/AnyHolder.h" |
7 | | #include "zserio/BitStreamReader.h" |
8 | | #include "zserio/BitStreamWriter.h" |
9 | | #include "zserio/Reflectable.h" |
10 | | #include "zserio/Traits.h" |
11 | | #include "zserio/pmr/PolymorphicAllocator.h" |
12 | | |
13 | | namespace zserio |
14 | | { |
15 | | |
16 | | namespace |
17 | | { |
18 | | |
19 | | // wrapper functions to prevent macro confusion with ',' in template parameters |
20 | | void assertTrue(bool value) |
21 | 10 | { |
22 | 10 | ASSERT_TRUE(value); |
23 | 10 | } |
24 | | |
25 | | void assertFalse(bool value) |
26 | 14 | { |
27 | 14 | ASSERT_FALSE(value); |
28 | 14 | } |
29 | | |
30 | | class DummyObjectInitialize |
31 | | { |
32 | | public: |
33 | | void initialize() |
34 | 1 | {} |
35 | | }; |
36 | | |
37 | | class DummyObjectInitializeChildren |
38 | | { |
39 | | public: |
40 | | void initializeChildren() |
41 | 1 | {} |
42 | | }; |
43 | | |
44 | | class DummyOwner |
45 | | {}; |
46 | | |
47 | | class DummyObjectWithOwnerType |
48 | | { |
49 | | public: |
50 | | using OwnerType = DummyOwner; |
51 | | }; |
52 | | |
53 | | class DummyObjectWithAllocator |
54 | | { |
55 | | public: |
56 | | using allocator_type = std::allocator<uint8_t>; |
57 | | }; |
58 | | |
59 | | class DummyObjectReflectable |
60 | | { |
61 | | public: |
62 | | IReflectablePtr reflectable() |
63 | 1 | { |
64 | 1 | return nullptr; |
65 | 1 | } |
66 | | }; |
67 | | |
68 | | class DummyObjectWithPackingContext |
69 | | { |
70 | | public: |
71 | | struct ZserioPackingContext |
72 | | {}; |
73 | | }; |
74 | | |
75 | | class DummyObjectInitializeOffset |
76 | | { |
77 | | public: |
78 | | using OwnerType = DummyOwner; |
79 | | |
80 | | void initializeOffset(OwnerType&, size_t, size_t) |
81 | 1 | {} |
82 | | }; |
83 | | |
84 | | class DummyObjectCheckOffset |
85 | | { |
86 | | public: |
87 | | using OwnerType = DummyOwner; |
88 | | |
89 | | void checkOffset(const OwnerType&, size_t, size_t) |
90 | 1 | {} |
91 | | }; |
92 | | |
93 | | class DummyObjectInitializeElement |
94 | | { |
95 | | public: |
96 | | using OwnerType = DummyOwner; |
97 | | |
98 | | void initializeElement(OwnerType&, DummyObjectInitializeChildren&, size_t) |
99 | 1 | {} |
100 | | }; |
101 | | |
102 | | enum class DummyEnum : uint8_t |
103 | | { |
104 | | ONE, |
105 | | TWO |
106 | | }; |
107 | | |
108 | | class DummyBitmask |
109 | | { |
110 | | public: |
111 | | using underlying_type = int; |
112 | | |
113 | | int getValue() |
114 | 1 | { |
115 | 1 | return 0; |
116 | 1 | } |
117 | | }; |
118 | | |
119 | | template <typename FIELD_TYPE, typename COMPOUND_TYPE, typename ALLOCATOR_TYPE, typename = void> |
120 | | struct has_field_ctor : std::false_type |
121 | | {}; |
122 | | |
123 | | template <typename FIELD_TYPE, typename COMPOUND_TYPE, typename ALLOCATOR_TYPE> |
124 | | struct has_field_ctor<FIELD_TYPE, COMPOUND_TYPE, ALLOCATOR_TYPE, |
125 | | detail::void_t<is_field_constructor_enabled_t<FIELD_TYPE, COMPOUND_TYPE, ALLOCATOR_TYPE>>> |
126 | | : std::true_type |
127 | | {}; |
128 | | |
129 | | } // namespace |
130 | | |
131 | | TEST(TraitsTest, isAllocator) |
132 | 1 | { |
133 | 1 | ASSERT_TRUE(is_allocator<std::allocator<uint8_t>>::value); |
134 | 1 | ASSERT_TRUE(is_allocator<std::allocator<std::vector<uint8_t>>>::value); |
135 | 1 | ASSERT_TRUE(is_allocator<pmr::PolymorphicAllocator<uint8_t>>::value); |
136 | 1 | ASSERT_TRUE(is_allocator<pmr::PolymorphicAllocator<std::vector<uint8_t>>>::value); |
137 | 1 | ASSERT_TRUE(is_allocator<pmr::PropagatingPolymorphicAllocator<uint8_t>>::value); |
138 | 1 | ASSERT_TRUE(is_allocator<pmr::PropagatingPolymorphicAllocator<std::vector<uint8_t>>>::value); |
139 | | |
140 | 1 | ASSERT_FALSE(is_allocator<int>::value); |
141 | 1 | ASSERT_FALSE(is_allocator<uint64_t>::value); |
142 | 1 | ASSERT_FALSE(is_allocator<std::vector<uint8_t>>::value); |
143 | 1 | ASSERT_FALSE(is_allocator<AnyHolder<>>::value); |
144 | 1 | ASSERT_FALSE(is_allocator<DummyObjectWithAllocator>::value); |
145 | 1 | } |
146 | | |
147 | | TEST(TraitsTest, isFirstAllocator) |
148 | 1 | { |
149 | 1 | assertTrue(is_first_allocator<std::allocator<uint8_t>, int>::value); |
150 | 1 | assertTrue(is_first_allocator<std::allocator<uint8_t>, std::allocator<uint8_t>>::value); |
151 | 1 | assertTrue(is_first_allocator<std::allocator<uint8_t>, std::allocator<uint8_t>, char>::value); |
152 | 1 | assertTrue(is_first_allocator<std::allocator<uint8_t>, int, std::allocator<uint8_t>>::value); |
153 | 1 | assertTrue(is_first_allocator<pmr::PolymorphicAllocator<uint8_t>, int, std::allocator<uint8_t>>::value); |
154 | 1 | assertTrue(is_first_allocator<pmr::PolymorphicAllocator<uint8_t>, char>::value); |
155 | | |
156 | 1 | assertFalse(is_first_allocator<int, std::allocator<uint8_t>>::value); |
157 | 1 | assertFalse(is_first_allocator<std::vector<uint8_t>, std::allocator<uint8_t>>::value); |
158 | 1 | assertFalse(is_first_allocator<char, std::allocator<uint8_t>, std::allocator<uint8_t>>::value); |
159 | 1 | assertFalse(is_first_allocator<int, std::allocator<uint8_t>, std::allocator<uint8_t>>::value); |
160 | 1 | assertFalse(is_first_allocator<int, pmr::PolymorphicAllocator<uint8_t>, std::allocator<uint8_t>>::value); |
161 | 1 | assertFalse(is_first_allocator<char, pmr::PolymorphicAllocator<uint8_t>>::value); |
162 | 1 | assertFalse(is_first_allocator<DummyObjectWithAllocator, pmr::PolymorphicAllocator<uint8_t>>::value); |
163 | 1 | } |
164 | | |
165 | | TEST(TraitsTest, hasOwnerType) |
166 | 1 | { |
167 | 1 | ASSERT_TRUE(has_owner_type<DummyObjectWithOwnerType>::value); |
168 | 1 | ASSERT_TRUE(has_owner_type<DummyObjectInitializeOffset>::value); |
169 | 1 | ASSERT_TRUE(has_owner_type<DummyObjectCheckOffset>::value); |
170 | 1 | ASSERT_TRUE(has_owner_type<DummyObjectInitializeElement>::value); |
171 | 1 | ASSERT_FALSE(has_owner_type<DummyObjectInitialize>::value); |
172 | 1 | ASSERT_FALSE(has_owner_type<DummyObjectInitializeChildren>::value); |
173 | 1 | ASSERT_FALSE(has_owner_type<DummyObjectWithPackingContext>::value); |
174 | 1 | ASSERT_FALSE(has_owner_type<DummyObjectWithAllocator>::value); |
175 | 1 | ASSERT_FALSE(has_owner_type<DummyEnum>::value); |
176 | 1 | ASSERT_FALSE(has_owner_type<DummyBitmask>::value); |
177 | 1 | ASSERT_FALSE(has_owner_type<std::string>::value); |
178 | 1 | ASSERT_FALSE(has_owner_type<std::vector<uint8_t>>::value); |
179 | 1 | ASSERT_FALSE(has_owner_type<std::vector<DummyObjectWithOwnerType>>::value); |
180 | 1 | } |
181 | | |
182 | | TEST(TraitsTest, hasZserioPackingContext) |
183 | 1 | { |
184 | 1 | ASSERT_TRUE(has_zserio_packing_context<DummyObjectWithPackingContext>::value); |
185 | 1 | ASSERT_FALSE(has_zserio_packing_context<DummyObjectInitialize>::value); |
186 | 1 | ASSERT_FALSE(has_zserio_packing_context<DummyObjectInitializeChildren>::value); |
187 | 1 | ASSERT_FALSE(has_zserio_packing_context<DummyObjectWithOwnerType>::value); |
188 | 1 | ASSERT_FALSE(has_zserio_packing_context<DummyObjectWithAllocator>::value); |
189 | 1 | ASSERT_FALSE(has_zserio_packing_context<DummyEnum>::value); |
190 | 1 | ASSERT_FALSE(has_zserio_packing_context<DummyBitmask>::value); |
191 | 1 | ASSERT_FALSE(has_zserio_packing_context<std::string>::value); |
192 | 1 | ASSERT_FALSE(has_zserio_packing_context<std::vector<uint8_t>>::value); |
193 | 1 | ASSERT_FALSE(has_zserio_packing_context<std::vector<DummyObjectWithPackingContext>>::value); |
194 | 1 | } |
195 | | |
196 | | TEST(TraitsTest, hasAllocator) |
197 | 1 | { |
198 | 1 | ASSERT_TRUE(has_allocator<DummyObjectWithAllocator>::value); |
199 | 1 | ASSERT_TRUE(has_allocator<std::string>::value); |
200 | 1 | ASSERT_TRUE(has_allocator<std::vector<uint8_t>>::value); |
201 | 1 | ASSERT_TRUE(has_allocator<std::vector<DummyObjectWithAllocator>>::value); |
202 | 1 | ASSERT_FALSE(has_allocator<DummyObjectInitialize>::value); |
203 | 1 | ASSERT_FALSE(has_allocator<DummyObjectInitializeChildren>::value); |
204 | 1 | ASSERT_FALSE(has_allocator<DummyObjectWithOwnerType>::value); |
205 | 1 | ASSERT_FALSE(has_allocator<DummyObjectWithPackingContext>::value); |
206 | 1 | ASSERT_FALSE(has_allocator<DummyEnum>::value); |
207 | 1 | ASSERT_FALSE(has_allocator<DummyBitmask>::value); |
208 | 1 | } |
209 | | |
210 | | TEST(TraitsTest, hasInitialize) |
211 | 1 | { |
212 | 1 | ASSERT_TRUE(has_initialize<DummyObjectInitialize>::value); |
213 | 1 | DummyObjectInitialize().initialize(); |
214 | 1 | ASSERT_FALSE(has_initialize<DummyObjectInitializeChildren>::value); |
215 | 1 | ASSERT_FALSE(has_initialize<DummyObjectWithOwnerType>::value); |
216 | 1 | ASSERT_FALSE(has_initialize<DummyObjectWithPackingContext>::value); |
217 | 1 | ASSERT_FALSE(has_initialize<DummyEnum>::value); |
218 | 1 | ASSERT_FALSE(has_initialize<DummyBitmask>::value); |
219 | 1 | ASSERT_FALSE(has_initialize<std::string>::value); |
220 | 1 | ASSERT_FALSE(has_initialize<std::vector<uint8_t>>::value); |
221 | 1 | } |
222 | | |
223 | | TEST(TraitsTest, hasInitializeChildren) |
224 | 1 | { |
225 | 1 | ASSERT_TRUE(has_initialize_children<DummyObjectInitializeChildren>::value); |
226 | 1 | DummyObjectInitializeChildren().initializeChildren(); |
227 | 1 | ASSERT_FALSE(has_initialize_children<DummyObjectInitialize>::value); |
228 | 1 | ASSERT_FALSE(has_initialize_children<DummyObjectWithOwnerType>::value); |
229 | 1 | ASSERT_FALSE(has_initialize_children<DummyObjectWithPackingContext>::value); |
230 | 1 | ASSERT_FALSE(has_initialize_children<DummyEnum>::value); |
231 | 1 | ASSERT_FALSE(has_initialize_children<DummyBitmask>::value); |
232 | 1 | ASSERT_FALSE(has_initialize_children<std::string>::value); |
233 | 1 | ASSERT_FALSE(has_initialize_children<std::vector<uint8_t>>::value); |
234 | 1 | } |
235 | | |
236 | | TEST(TraitsTest, hasReflectable) |
237 | 1 | { |
238 | 1 | ASSERT_TRUE(has_reflectable<DummyObjectReflectable>::value); |
239 | 1 | ASSERT_EQ(nullptr, DummyObjectReflectable().reflectable()); |
240 | 1 | ASSERT_FALSE(has_reflectable<DummyObjectInitialize>::value); |
241 | 1 | ASSERT_FALSE(has_reflectable<DummyObjectWithOwnerType>::value); |
242 | 1 | ASSERT_FALSE(has_reflectable<DummyObjectWithPackingContext>::value); |
243 | 1 | ASSERT_FALSE(has_reflectable<DummyObjectWithAllocator>::value); |
244 | 1 | ASSERT_FALSE(has_reflectable<DummyEnum>::value); |
245 | 1 | ASSERT_FALSE(has_reflectable<DummyBitmask>::value); |
246 | 1 | ASSERT_FALSE(has_reflectable<std::string>::value); |
247 | 1 | ASSERT_FALSE(has_reflectable<std::vector<uint8_t>>::value); |
248 | 1 | } |
249 | | |
250 | | TEST(TraitsTest, hasInitializeOffset) |
251 | 1 | { |
252 | 1 | ASSERT_TRUE(has_initialize_offset<DummyObjectInitializeOffset>::value); |
253 | 1 | DummyOwner owner; |
254 | 1 | DummyObjectInitializeOffset().initializeOffset(owner, 0, 0); |
255 | 1 | ASSERT_FALSE(has_initialize_offset<DummyObjectCheckOffset>::value); |
256 | 1 | ASSERT_FALSE(has_initialize_offset<DummyObjectInitializeElement>::value); |
257 | 1 | ASSERT_FALSE(has_initialize_offset<DummyObjectInitialize>::value); |
258 | 1 | ASSERT_FALSE(has_initialize_offset<DummyObjectInitializeChildren>::value); |
259 | 1 | ASSERT_FALSE(has_initialize_offset<DummyObjectReflectable>::value); |
260 | 1 | ASSERT_FALSE(has_initialize_offset<DummyObjectWithOwnerType>::value); |
261 | 1 | ASSERT_FALSE(has_initialize_offset<DummyObjectWithAllocator>::value); |
262 | 1 | ASSERT_FALSE(has_initialize_offset<DummyObjectWithPackingContext>::value); |
263 | 1 | } |
264 | | |
265 | | TEST(TraitsTest, hasCheckOffset) |
266 | 1 | { |
267 | 1 | ASSERT_TRUE(has_check_offset<DummyObjectCheckOffset>::value); |
268 | 1 | DummyObjectCheckOffset().checkOffset(DummyOwner(), 0, 0); |
269 | 1 | ASSERT_FALSE(has_check_offset<DummyObjectInitializeOffset>::value); |
270 | 1 | ASSERT_FALSE(has_check_offset<DummyObjectInitializeElement>::value); |
271 | 1 | ASSERT_FALSE(has_check_offset<DummyObjectInitialize>::value); |
272 | 1 | ASSERT_FALSE(has_check_offset<DummyObjectInitializeChildren>::value); |
273 | 1 | ASSERT_FALSE(has_check_offset<DummyObjectReflectable>::value); |
274 | 1 | ASSERT_FALSE(has_check_offset<DummyObjectWithOwnerType>::value); |
275 | 1 | ASSERT_FALSE(has_check_offset<DummyObjectWithAllocator>::value); |
276 | 1 | ASSERT_FALSE(has_check_offset<DummyObjectWithPackingContext>::value); |
277 | 1 | } |
278 | | |
279 | | TEST(TraitsTest, hasInitializeElement) |
280 | 1 | { |
281 | 1 | ASSERT_TRUE(has_initialize_element<DummyObjectInitializeElement>::value); |
282 | 1 | DummyOwner owner; |
283 | 1 | DummyObjectInitializeChildren element; |
284 | 1 | DummyObjectInitializeElement().initializeElement(owner, element, 0); |
285 | 1 | ASSERT_FALSE(has_initialize_element<DummyObjectInitializeOffset>::value); |
286 | 1 | ASSERT_FALSE(has_initialize_element<DummyObjectCheckOffset>::value); |
287 | 1 | ASSERT_FALSE(has_initialize_element<DummyObjectInitialize>::value); |
288 | 1 | ASSERT_FALSE(has_initialize_element<DummyObjectInitializeChildren>::value); |
289 | 1 | ASSERT_FALSE(has_initialize_element<DummyObjectReflectable>::value); |
290 | 1 | ASSERT_FALSE(has_initialize_element<DummyObjectWithOwnerType>::value); |
291 | 1 | ASSERT_FALSE(has_initialize_element<DummyObjectWithAllocator>::value); |
292 | 1 | ASSERT_FALSE(has_initialize_element<DummyObjectWithPackingContext>::value); |
293 | 1 | } |
294 | | |
295 | | TEST(TraitsTest, isBitmask) |
296 | 1 | { |
297 | 1 | ASSERT_TRUE(is_bitmask<DummyBitmask>::value); |
298 | 1 | ASSERT_EQ(0, DummyBitmask().getValue()); |
299 | 1 | ASSERT_FALSE(is_bitmask<DummyObjectInitializeChildren>::value); |
300 | 1 | ASSERT_FALSE(is_bitmask<DummyObjectInitialize>::value); |
301 | 1 | ASSERT_FALSE(is_bitmask<DummyObjectWithOwnerType>::value); |
302 | 1 | ASSERT_FALSE(is_bitmask<DummyObjectWithPackingContext>::value); |
303 | 1 | ASSERT_FALSE(is_bitmask<DummyObjectWithAllocator>::value); |
304 | 1 | ASSERT_FALSE(is_bitmask<DummyEnum>::value); |
305 | 1 | ASSERT_FALSE(is_bitmask<std::string>::value); |
306 | 1 | ASSERT_FALSE(is_bitmask<std::vector<uint8_t>>::value); |
307 | 1 | } |
308 | | |
309 | | TEST(TraitsTest, isSpan) |
310 | 1 | { |
311 | 1 | ASSERT_TRUE(is_span<zserio::Span<uint8_t>>::value); |
312 | 1 | ASSERT_TRUE(is_span<zserio::Span<const uint8_t>>::value); |
313 | 1 | ASSERT_TRUE(is_span<zserio::Span<char* const>>::value); |
314 | 1 | ASSERT_TRUE(is_span<zserio::Span<char*>>::value); |
315 | 1 | assertFalse(is_span<std::array<uint8_t, 2>>::value); |
316 | 1 | ASSERT_FALSE(is_span<std::vector<uint8_t>>::value); |
317 | 1 | ASSERT_FALSE(is_span<uint8_t>::value); |
318 | 1 | ASSERT_FALSE(is_span<std::string>::value); |
319 | 1 | ASSERT_FALSE(is_span<DummyObjectInitializeChildren>::value); |
320 | 1 | ASSERT_FALSE(is_span<DummyObjectInitialize>::value); |
321 | 1 | ASSERT_FALSE(is_span<DummyObjectWithOwnerType>::value); |
322 | 1 | ASSERT_FALSE(is_span<DummyObjectWithPackingContext>::value); |
323 | 1 | ASSERT_FALSE(is_span<DummyObjectWithAllocator>::value); |
324 | 1 | } |
325 | | |
326 | | TEST(TraitsTest, isFieldConstructorEnabled) |
327 | 1 | { |
328 | 1 | assertTrue(has_field_ctor<int, DummyObjectInitialize, std::allocator<uint8_t>>::value); |
329 | 1 | assertTrue(has_field_ctor<std::string, DummyObjectInitialize, std::allocator<uint8_t>>::value); |
330 | 1 | assertTrue(has_field_ctor<DummyObjectInitializeChildren, DummyObjectInitialize, |
331 | 1 | std::allocator<uint8_t>>::value); |
332 | 1 | assertTrue(has_field_ctor<DummyObjectWithPackingContext::ZserioPackingContext, DummyObjectInitialize, |
333 | 1 | std::allocator<uint8_t>>::value); |
334 | 1 | assertFalse(has_field_ctor<DummyObjectInitialize, DummyObjectInitialize, std::allocator<uint8_t>>::value); |
335 | 1 | assertFalse(has_field_ctor<std::allocator<uint8_t>, DummyObjectInitialize, std::allocator<uint8_t>>::value); |
336 | 1 | assertFalse(has_field_ctor<BitStreamReader, DummyObjectInitialize, std::allocator<uint8_t>>::value); |
337 | 1 | assertFalse(has_field_ctor<PropagateAllocatorT, DummyObjectInitialize, std::allocator<uint8_t>>::value); |
338 | 1 | assertFalse(has_field_ctor<NoInitT, DummyObjectInitialize, std::allocator<uint8_t>>::value); |
339 | 1 | assertFalse(has_field_ctor<DummyObjectWithPackingContext::ZserioPackingContext, |
340 | 1 | DummyObjectWithPackingContext, std::allocator<uint8_t>>::value); |
341 | 1 | } |
342 | | |
343 | | } // namespace zserio |