Coverage Report

Created: 2023-12-13 14:58

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