Coverage Report

Created: 2024-04-30 09:35

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