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