Coverage Report

Created: 2026-03-05 16:18

test/zserio/ArrayViewTest.cpp
Line
Count
Source
1
#include <algorithm>
2
3
#include "gtest/gtest.h"
4
#include "zserio/ArrayView.h"
5
#include "zserio/Types.h"
6
7
namespace zserio
8
{
9
10
namespace
11
{
12
13
struct TestObject
14
{
15
    UInt32 field;
16
17
    constexpr bool operator==(const TestObject& other) const
18
15
    {
19
15
        return field == other.field;
20
15
    }
21
22
    constexpr bool operator<(const TestObject& other) const
23
3
    {
24
3
        return field < other.field;
25
3
    }
26
};
27
28
struct VarDynInt16Owner
29
{
30
    uint8_t numBits = 10;
31
};
32
33
} // namespace
34
35
template <>
36
class View<TestObject>
37
{
38
public:
39
    explicit View(const TestObject& data) :
40
58
            m_data(data)
41
58
    {}
42
43
    UInt32 field() const
44
35
    {
45
35
        return m_data.field;
46
35
    }
47
48
    constexpr bool operator==(const View& other) const
49
8
    {
50
8
        return m_data == other.m_data;
51
8
    }
52
53
    constexpr bool operator!=(const View& other) const
54
4
    {
55
4
        return !operator==(other);
56
4
    }
57
58
    constexpr bool operator<(const View& other) const
59
3
    {
60
3
        return m_data < other.m_data;
61
3
    }
62
63
private:
64
    const TestObject& m_data;
65
};
66
67
namespace detail
68
{
69
70
template <>
71
struct ObjectTraits<TestObject>
72
{
73
    struct PackingContext
74
    {
75
        DeltaContext field;
76
    };
77
78
    static BitSize bitSizeOf(const View<TestObject>& view, BitSize bitPosition)
79
2
    {
80
2
        BitSize endBitPosition = bitPosition;
81
2
        endBitPosition += detail::bitSizeOf(view.field(), endBitPosition);
82
2
        return endBitPosition - bitPosition;
83
2
    }
84
85
    static void write(BitStreamWriter& writer, const View<TestObject>& view)
86
2
    {
87
2
        detail::write(writer, view.field());
88
2
    }
89
90
    static View<TestObject> read(BitStreamReader& reader, TestObject& data)
91
2
    {
92
2
        View<TestObject> view(data);
93
2
        detail::read(reader, data.field);
94
2
        return view;
95
2
    }
96
97
    static void initContext(PackingContext& packingContext, const View<TestObject>& view)
98
10
    {
99
10
        detail::initContext(packingContext.field, view.field());
100
10
    }
101
102
    static BitSize bitSizeOf(PackingContext& packingContext, const View<TestObject>& view, BitSize bitPosition)
103
5
    {
104
5
        BitSize endBitPosition = bitPosition;
105
5
        endBitPosition += detail::bitSizeOf(packingContext.field, view.field(), endBitPosition);
106
5
        return endBitPosition - bitPosition;
107
5
    }
108
109
    static void write(PackingContext& packingContext, BitStreamWriter& writer, const View<TestObject>& view)
110
5
    {
111
5
        detail::write(packingContext.field, writer, view.field());
112
5
    }
113
114
    static void read(PackingContext& packingContext, BitStreamReader& reader, TestObject& data)
115
5
    {
116
117
5
        detail::read(packingContext.field, reader, data.field);
118
5
    }
119
};
120
121
} // namespace detail
122
123
struct VarDynInt16ArrayTraits
124
{
125
    using OwnerType = VarDynInt16Owner;
126
127
    static View<DynInt16> at(const VarDynInt16Owner& owner, const DynInt16& element, size_t)
128
48
    {
129
48
        return View<DynInt16>(element, owner.numBits);
130
48
    }
131
132
    static void read(BitStreamReader& reader, const VarDynInt16Owner& owner, DynInt16& element, size_t)
133
2
    {
134
2
        detail::read(reader, element, owner.numBits);
135
2
    }
136
137
    static void read(detail::DeltaContext& context, BitStreamReader& reader, const VarDynInt16Owner& owner,
138
            DynInt16& element, size_t)
139
7
    {
140
7
        detail::read(context, reader, element, owner.numBits);
141
7
    }
142
};
143
144
TEST(ArrayViewTest, boolArray)
145
1
{
146
1
    Vector<Bool> rawArray1{true, false};
147
1
    Vector<Bool> rawArray2{true, true};
148
149
1
    ArrayView<const Bool> array1(rawArray1);
150
1
    ASSERT_EQ(rawArray1.at(0), array1.at(0));
151
1
    ASSERT_EQ(rawArray1.at(1), array1.at(1));
152
153
1
    ArrayView<const Bool> array2(rawArray2);
154
1
    ASSERT_FALSE(array1 == array2);
155
1
    ASSERT_TRUE(array1 != array2);
156
1
    ASSERT_LT(array1, array2);
157
158
1
    const BitSize bitSize = detail::bitSizeOf<detail::ArrayType::AUTO>(array1);
159
1
    BitBuffer buffer(bitSize);
160
1
    BitStreamWriter writer(buffer);
161
1
    detail::write<detail::ArrayType::AUTO>(writer, array1);
162
1
    ASSERT_EQ(bitSize, writer.getBitPosition());
163
164
1
    BitStreamReader reader(buffer);
165
1
    Vector<Bool> readRawArray;
166
1
    detail::read<detail::ArrayType::AUTO>(reader, readRawArray);
167
1
    ASSERT_EQ(bitSize, reader.getBitPosition());
168
1
    ASSERT_EQ(rawArray1, readRawArray);
169
1
}
170
171
TEST(ArrayViewTest, boolPackedArray)
172
1
{
173
1
    Vector<Bool> rawArray{true, false, true, false, true};
174
1
    ArrayView<const Bool> array(rawArray);
175
176
1
    const BitSize packedBitSize = detail::bitSizeOfPacked<detail::ArrayType::AUTO>(array);
177
1
    BitBuffer buffer(packedBitSize);
178
1
    BitStreamWriter writer(buffer);
179
1
    detail::writePacked<detail::ArrayType::AUTO>(writer, array);
180
1
    ASSERT_EQ(packedBitSize, writer.getBitPosition());
181
182
1
    BitStreamReader reader(buffer);
183
1
    Vector<Bool> readRawArray;
184
1
    detail::readPacked<detail::ArrayType::AUTO>(reader, readRawArray, rawArray.size());
185
1
    ASSERT_EQ(packedBitSize, reader.getBitPosition());
186
1
    ASSERT_EQ(rawArray, readRawArray);
187
1
}
188
189
TEST(ArrayViewTest, int8Array)
190
1
{
191
1
    Vector<Int8> rawArray1{0, 13};
192
1
    Vector<Int8> rawArray2{0, 42};
193
194
1
    ArrayView<const Int8> array1(rawArray1);
195
1
    ASSERT_EQ(rawArray1.at(0), array1.at(0));
196
1
    ASSERT_EQ(rawArray1.at(1), array1.at(1));
197
198
1
    ArrayView<const Int8> array2(rawArray2);
199
1
    ASSERT_FALSE(array1 == array2);
200
1
    ASSERT_TRUE(array1 != array2);
201
1
    ASSERT_LT(array1, array2);
202
203
1
    const BitSize bitSize = detail::bitSizeOf<detail::ArrayType::AUTO>(array1);
204
1
    BitBuffer buffer(bitSize);
205
1
    BitStreamWriter writer(buffer);
206
1
    detail::write<detail::ArrayType::AUTO>(writer, array1);
207
1
    ASSERT_EQ(bitSize, writer.getBitPosition());
208
209
1
    BitStreamReader reader(buffer);
210
1
    Vector<Int8> readRawArray;
211
1
    detail::read<detail::ArrayType::AUTO>(reader, readRawArray);
212
1
    ASSERT_EQ(bitSize, reader.getBitPosition());
213
1
    ASSERT_EQ(rawArray1, readRawArray);
214
1
}
215
216
TEST(ArrayViewTest, int8PackedArray)
217
1
{
218
1
    Vector<Int8> rawArray = {-4, -3, -1, 0, 2, 4, 6, 8, 10, 10, 11};
219
1
    ArrayView<const Int8> array(rawArray);
220
221
1
    static_assert(detail::is_packable_v<Int8>, "shall be packable");
222
1
    static_assert(detail::is_packable_v<const Int8>, "shall be packable");
223
224
    // maxBitNumber == 2
225
    // packingDescriptor 7 + firstElement 8 + 10 * (maxBitNumber 2 + 1)
226
1
    static constexpr BitSize packedBitSize = 45;
227
1
    ASSERT_EQ(packedBitSize, detail::bitSizeOfPacked<detail::ArrayType::NORMAL>(array));
228
229
1
    BitBuffer buffer(packedBitSize);
230
1
    BitStreamWriter writer(buffer);
231
1
    detail::writePacked<detail::ArrayType::NORMAL>(writer, array);
232
1
    ASSERT_EQ(packedBitSize, writer.getBitPosition());
233
234
1
    BitStreamReader reader(buffer);
235
1
    Vector<Int8> readRawArray;
236
1
    detail::readPacked<detail::ArrayType::NORMAL>(reader, readRawArray, rawArray.size());
237
1
    ASSERT_EQ(rawArray, readRawArray);
238
239
1
    ASSERT_EQ(rawArray.size(), array.size());
240
1
    ASSERT_FALSE(array.empty());
241
242
1
    Vector<Int8> emptyRawArray;
243
1
    ArrayView<const Int8> emptyArray(emptyRawArray);
244
1
    ASSERT_TRUE(emptyArray.empty());
245
246
1
    ASSERT_THROW(emptyArray.front(), CppRuntimeException);
247
248
1
    ASSERT_EQ(rawArray.front(), array.front());
249
1
    ASSERT_EQ(rawArray.back(), array.back());
250
251
1
    auto it = array.begin();
252
1
    ASSERT_EQ(-4, *it);
253
1
    ASSERT_EQ(-1, it[2]);
254
1
    it += 2;
255
1
    ASSERT_EQ(-1, *it);
256
1
    ASSERT_EQ(-3, it[-1]);
257
1
    it -= 1;
258
1
    ASSERT_EQ(-3, *it);
259
1
    auto otherIt = it + 2;
260
1
    ASSERT_EQ(0, *otherIt);
261
1
    ASSERT_EQ(2, *(++otherIt));
262
1
    ASSERT_EQ(2, *(otherIt++));
263
1
    ASSERT_EQ(4, *otherIt);
264
1
    ASSERT_EQ(2, *(--otherIt));
265
1
    ASSERT_EQ(2, *(otherIt--));
266
1
    ASSERT_EQ(0, *otherIt);
267
1
    otherIt = 2 + it;
268
1
    ASSERT_EQ(0, *otherIt);
269
1
    otherIt = it - 1;
270
1
    ASSERT_EQ(-4, *otherIt);
271
1
    ASSERT_EQ(1, it - otherIt);
272
1
    ASSERT_EQ(-1, otherIt - it);
273
1
    ASSERT_EQ(array.size(), array.end() - array.begin());
274
275
1
    ASSERT_TRUE(otherIt == array.begin());
276
1
    ASSERT_FALSE(otherIt == array.end());
277
278
1
    ASSERT_TRUE(otherIt != array.end());
279
1
    ASSERT_FALSE(otherIt != array.begin());
280
281
1
    ASSERT_TRUE(otherIt < array.end());
282
1
    ASSERT_FALSE(array.end() < otherIt);
283
284
1
    ASSERT_TRUE(array.end() > array.begin());
285
1
    ASSERT_FALSE(array.begin() > array.end());
286
287
1
    ASSERT_TRUE(array.begin() <= array.end());
288
1
    ASSERT_TRUE(array.begin() <= array.begin());
289
1
    ASSERT_FALSE(array.end() <= array.begin());
290
291
1
    ASSERT_TRUE(array.end() >= array.begin());
292
1
    ASSERT_TRUE(array.end() >= array.end());
293
1
    ASSERT_FALSE(array.begin() >= array.end());
294
295
1
    size_t i = 0;
296
1
    for (auto element : array)
297
11
    {
298
11
        ASSERT_EQ(rawArray[i++], element);
299
11
    }
300
301
1
    i = array.size() - 1;
302
12
    for (auto rit = array.rbegin(); rit < array.rend(); 
++rit11
)
303
11
    {
304
11
        ASSERT_EQ(rawArray[i--], *rit);
305
11
    }
306
307
5
    
auto foundIt = std::find_if(array.begin(), array.end(), [](auto value) 1
{
308
5
        return value > 0;
309
5
    });
310
1
    ASSERT_NE(array.end(), foundIt);
311
1
    ASSERT_EQ(2, *foundIt);
312
1
}
313
314
TEST(ArrayViewTest, fixedDynInt16Array)
315
1
{
316
1
    Vector<Int<9>> rawArray1{-2, 13};
317
1
    Vector<Int<9>> rawArray2{-2, 42};
318
319
1
    ArrayView<const Int<9>> array1(rawArray1);
320
1
    ASSERT_EQ(rawArray1.at(0), array1.at(0));
321
1
    ASSERT_EQ(rawArray1.at(1), array1.at(1));
322
323
1
    ArrayView<const Int<9>> array2(rawArray2);
324
1
    ASSERT_FALSE(array1 == array2);
325
1
    ASSERT_TRUE(array1 != array2);
326
1
    ASSERT_LT(array1, array2);
327
328
1
    const BitSize bitSize = detail::bitSizeOf<detail::ArrayType::AUTO>(array1);
329
1
    BitBuffer buffer(bitSize);
330
1
    BitStreamWriter writer(buffer);
331
1
    detail::write<detail::ArrayType::AUTO>(writer, array1);
332
1
    ASSERT_EQ(bitSize, writer.getBitPosition());
333
334
1
    BitStreamReader reader(buffer);
335
1
    Vector<Int<9>> readRawArray;
336
1
    detail::read<detail::ArrayType::AUTO>(reader, readRawArray, rawArray1.size());
337
1
    ASSERT_EQ(bitSize, reader.getBitPosition());
338
1
    ASSERT_EQ(rawArray1, readRawArray);
339
1
}
340
341
TEST(ArrayViewTest, variableDynInt16Array)
342
1
{
343
1
    Vector<DynInt16> rawArray1{-2, 13};
344
1
    Vector<DynInt16> rawArray2{-2, 42};
345
346
1
    VarDynInt16Owner owner;
347
348
1
    ArrayView<const DynInt16, VarDynInt16ArrayTraits> array1(rawArray1, owner);
349
1
    ASSERT_EQ(rawArray1.at(0), array1.at(0).value());
350
1
    ASSERT_EQ(rawArray1.at(1), array1.at(1).value());
351
352
1
    ArrayView<const DynInt16, VarDynInt16ArrayTraits> array2(rawArray2, owner);
353
1
    ASSERT_FALSE(array1 == array2);
354
1
    ASSERT_TRUE(array1 != array2);
355
1
    ASSERT_LT(array1, array2);
356
357
1
    const BitSize bitSize = detail::bitSizeOf<detail::ArrayType::AUTO>(array1);
358
1
    BitBuffer buffer(bitSize);
359
1
    BitStreamWriter writer(buffer);
360
1
    detail::write<detail::ArrayType::AUTO>(writer, array1);
361
1
    ASSERT_EQ(bitSize, writer.getBitPosition());
362
363
1
    BitStreamReader reader(buffer);
364
1
    Vector<DynInt16> readRawArray;
365
1
    detail::readWithTraits<detail::ArrayType::AUTO, VarDynInt16ArrayTraits>(
366
1
            reader, readRawArray, owner, rawArray1.size());
367
1
    ASSERT_EQ(bitSize, reader.getBitPosition());
368
1
    ASSERT_EQ(rawArray1, readRawArray);
369
1
}
370
371
TEST(ArrayViewTest, variableDynInt16PackedArray)
372
1
{
373
1
    Vector<DynInt16> rawArray{-2, 0, 2, 4, 6, 8, 10};
374
375
1
    VarDynInt16Owner owner;
376
1
    ArrayView<const DynInt16, VarDynInt16ArrayTraits> array(rawArray, owner);
377
378
    // maxBitNumber == 2
379
    // packingDescriptor 7 + firstElement 10 + 6 * (maxBitNumber 2 + 1)
380
1
    const BitSize packedBitSize = 35;
381
1
    ASSERT_EQ(packedBitSize, detail::bitSizeOfPacked<detail::ArrayType::NORMAL>(array));
382
383
1
    BitBuffer buffer(packedBitSize);
384
1
    BitStreamWriter writer(buffer);
385
1
    detail::writePacked<detail::ArrayType::NORMAL>(writer, array);
386
1
    ASSERT_EQ(packedBitSize, writer.getBitPosition());
387
388
1
    BitStreamReader reader(buffer);
389
1
    Vector<DynInt16> readRawArray;
390
1
    detail::readPackedWithTraits<detail::ArrayType::NORMAL, VarDynInt16ArrayTraits>(
391
1
            reader, readRawArray, owner, rawArray.size());
392
1
    ASSERT_EQ(packedBitSize, reader.getBitPosition());
393
1
    ASSERT_EQ(rawArray, readRawArray);
394
1
}
395
396
TEST(ArrayViewTest, varUInt16Array)
397
1
{
398
1
    Vector<VarUInt16> rawArray1{0, 13};
399
1
    Vector<VarUInt16> rawArray2{0, 42};
400
401
1
    ArrayView<const VarUInt16> array1(rawArray1);
402
1
    ASSERT_EQ(rawArray1.at(0), array1.at(0));
403
1
    ASSERT_EQ(rawArray1.at(1), array1.at(1));
404
405
1
    ArrayView<const VarUInt16> array2(rawArray2);
406
1
    ASSERT_FALSE(array1 == array2);
407
1
    ASSERT_TRUE(array1 != array2);
408
1
    ASSERT_LT(array1, array2);
409
410
1
    const BitSize bitSize = detail::bitSizeOf<detail::ArrayType::AUTO>(array1);
411
1
    BitBuffer buffer(bitSize);
412
1
    BitStreamWriter writer(buffer);
413
1
    detail::write<detail::ArrayType::AUTO>(writer, array1);
414
1
    ASSERT_EQ(bitSize, writer.getBitPosition());
415
416
1
    BitStreamReader reader(buffer);
417
1
    Vector<VarUInt16> readRawArray;
418
1
    detail::read<detail::ArrayType::AUTO>(reader, readRawArray, rawArray1.size());
419
1
    ASSERT_EQ(bitSize, reader.getBitPosition());
420
1
    ASSERT_EQ(rawArray1, readRawArray);
421
1
}
422
423
TEST(ArrayViewTest, varUInt16PackedArray)
424
1
{
425
1
    Vector<VarUInt16> rawArray{0, 2, 4, 6, 8, 10, 12};
426
1
    ArrayView<const VarUInt16> array(rawArray);
427
428
1
    const BitSize packedBitSize = detail::bitSizeOfPacked<detail::ArrayType::AUTO>(array);
429
1
    BitBuffer buffer(packedBitSize);
430
1
    BitStreamWriter writer(buffer);
431
1
    detail::writePacked<detail::ArrayType::AUTO>(writer, array);
432
1
    ASSERT_EQ(packedBitSize, writer.getBitPosition());
433
434
1
    BitStreamReader reader(buffer);
435
1
    Vector<VarUInt16> readRawArray;
436
1
    detail::readPacked<detail::ArrayType::AUTO>(reader, readRawArray, rawArray.size());
437
1
    ASSERT_EQ(packedBitSize, reader.getBitPosition());
438
1
    ASSERT_EQ(rawArray, readRawArray);
439
1
}
440
441
TEST(ArrayViewTest, float16Array)
442
1
{
443
1
    Vector<Float16> rawArray1{-9.0F, 0.0F, 10.0F};
444
1
    Vector<Float16> rawArray2{-9.0F, 0.0F, 10.1F};
445
446
1
    ArrayView<const Float16> array1(rawArray1);
447
1
    ArrayView<const Float16> array2(rawArray2);
448
449
1
    ASSERT_EQ(16, ArrayTraits<Float16>::bitSizeOf());
450
451
1
    ASSERT_LT(array1, array2);
452
1
    ASSERT_GT(array2, array1);
453
454
1
    const BitSize bitSize = detail::bitSizeOf<detail::ArrayType::AUTO>(array1);
455
1
    BitBuffer buffer(bitSize);
456
1
    BitStreamWriter writer(buffer);
457
1
    detail::write<detail::ArrayType::AUTO>(writer, array1);
458
1
    ASSERT_EQ(bitSize, writer.getBitPosition());
459
460
1
    BitStreamReader reader(buffer);
461
1
    Vector<Float16> readRawArray;
462
1
    detail::read<detail::ArrayType::AUTO>(reader, readRawArray, rawArray1.size());
463
1
    ASSERT_EQ(bitSize, reader.getBitPosition());
464
1
    ASSERT_EQ(rawArray1, readRawArray);
465
1
}
466
467
TEST(ArrayViewTest, bytesArray)
468
1
{
469
1
    Vector<Bytes> rawArray1{{{{1, 255}}, {{127, 128}}}};
470
1
    Vector<Bytes> rawArray2{{{{1, 255}}, {{127, 129}}}};
471
472
1
    ArrayView<const Bytes> array1(rawArray1);
473
1
    ArrayView<const Bytes> array2(rawArray2);
474
475
1
    ASSERT_TRUE(std::equal(
476
1
            rawArray1.begin(), rawArray1.end(), array1.zserioData().begin(), array1.zserioData().end()));
477
478
1
    constexpr bool isSpan = std::is_same_v<Span<const uint8_t>, decltype(array1.at(0))>;
479
1
    ASSERT_TRUE(isSpan);
480
481
1
    ASSERT_TRUE(std::equal(
482
1
            rawArray1.at(0).begin(), rawArray1.at(0).end(), array1.at(0).begin(), array1.at(0).end()));
483
1
    ASSERT_TRUE(std::equal(
484
1
            rawArray1.at(1).begin(), rawArray1.at(1).end(), array1.at(1).begin(), array1.at(1).end()));
485
486
1
    ASSERT_NE(array1, array2);
487
1
    ASSERT_LT(array1, array2);
488
489
1
    const BitSize bitSize = detail::bitSizeOf<detail::ArrayType::AUTO>(array1);
490
1
    BitBuffer buffer(bitSize);
491
1
    BitStreamWriter writer(buffer);
492
1
    detail::write<detail::ArrayType::AUTO>(writer, array1);
493
1
    ASSERT_EQ(bitSize, writer.getBitPosition());
494
495
1
    BitStreamReader reader(buffer);
496
1
    Vector<Bytes> readRawArray;
497
1
    detail::read<detail::ArrayType::AUTO>(reader, readRawArray, rawArray1.size());
498
1
    ASSERT_EQ(bitSize, reader.getBitPosition());
499
1
    ASSERT_EQ(rawArray1, readRawArray);
500
1
}
501
502
TEST(ArrayViewTest, stringArray)
503
1
{
504
1
    Vector<std::string> rawArray1 = {"String0", "String1", "String2"};
505
1
    Vector<std::string> rawArray2 = {"String0", "String1", "String3"};
506
507
1
    ArrayView<const std::string> array1(rawArray1);
508
1
    ArrayView<const std::string> array2(rawArray2);
509
510
1
    constexpr bool isStringView = std::is_same_v<std::string_view, decltype(array1.at(0))>;
511
1
    ASSERT_TRUE(isStringView);
512
513
1
    ASSERT_EQ(rawArray1.at(0), array1.at(0));
514
1
    ASSERT_EQ(rawArray1.at(1), array1.at(1));
515
1
    ASSERT_EQ(rawArray1.at(2), array1.at(2));
516
517
1
    ASSERT_NE(array1, array2);
518
1
    ASSERT_LT(array1, array2);
519
520
1
    const BitSize bitSize = detail::bitSizeOf<detail::ArrayType::AUTO>(array1);
521
1
    BitBuffer buffer(bitSize);
522
1
    BitStreamWriter writer(buffer);
523
1
    detail::write<detail::ArrayType::AUTO>(writer, array1);
524
1
    ASSERT_EQ(bitSize, writer.getBitPosition());
525
526
1
    BitStreamReader reader(buffer);
527
1
    Vector<std::string> readRawArray;
528
1
    detail::read<detail::ArrayType::AUTO>(reader, readRawArray, rawArray1.size());
529
1
    ASSERT_EQ(bitSize, reader.getBitPosition());
530
1
    ASSERT_EQ(rawArray1, readRawArray);
531
1
}
532
533
TEST(ArrayViewTest, testObjectArray)
534
1
{
535
1
    Vector<TestObject> rawArray1{TestObject{0}, TestObject{13}};
536
1
    Vector<TestObject> rawArray2{TestObject{0}, TestObject{42}};
537
538
1
    ArrayView<const TestObject> array1(rawArray1);
539
1
    ASSERT_EQ(rawArray1.at(0).field, array1.at(0).field());
540
1
    ASSERT_EQ(rawArray1.at(1).field, array1.at(1).field());
541
542
1
    ArrayView<const TestObject> array2(rawArray2);
543
544
1
    ASSERT_FALSE(array1 == array2);
545
1
    ASSERT_TRUE(array1 != array2);
546
1
    ASSERT_LT(array1, array2);
547
548
1
    const BitSize bitSize = detail::bitSizeOf<detail::ArrayType::AUTO>(array1);
549
1
    BitBuffer buffer(bitSize);
550
1
    BitStreamWriter writer(buffer);
551
1
    detail::write<detail::ArrayType::AUTO>(writer, array1);
552
1
    ASSERT_EQ(bitSize, writer.getBitPosition());
553
554
1
    BitStreamReader reader(buffer);
555
1
    Vector<TestObject> readRawArray;
556
1
    detail::read<detail::ArrayType::AUTO>(reader, readRawArray);
557
1
    ASSERT_EQ(bitSize, reader.getBitPosition());
558
1
    ASSERT_EQ(rawArray1, readRawArray);
559
560
1
    ASSERT_FALSE(array1.empty());
561
1
    ASSERT_EQ(0, array1.front().field());
562
1
    ASSERT_EQ(13, array1.back().field());
563
564
1
    size_t i = 0;
565
1
    for (auto object : array1)
566
2
    {
567
2
        ASSERT_EQ(i++ == 0 ? 0 : 13, object.field());
568
2
    }
569
570
1
    TestObject object{13};
571
1
    zserio::View view(object);
572
1
    ASSERT_EQ(view, *(array1.begin() + 1));
573
1
    ASSERT_EQ(0, array1.begin()->field());
574
1
    ASSERT_EQ(view, array1.begin()[1]);
575
1
    ASSERT_EQ(array1.begin(), array1.end() - 2);
576
1
    ASSERT_EQ(*array1.begin(), *(array1.end() - 2));
577
1
    ASSERT_EQ(array1.size(), array1.end() - array1.begin());
578
579
2
    
auto foundIt = std::find_if(array1.begin(), array1.end(), [](const zserio::View<TestObject>& element) 1
{
580
2
        return element.field() != 0;
581
2
    });
582
1
    ASSERT_NE(array1.end(), foundIt);
583
1
    ASSERT_EQ(array1.at(1), *foundIt);
584
585
2
    
auto notFoundIt = std::find_if(array1.begin(), array1.end(), [](const zserio::View<TestObject>& element) 1
{
586
2
        return element.field() > 13;
587
2
    });
588
1
    ASSERT_EQ(array1.end(), notFoundIt);
589
1
}
590
591
TEST(ArrayViewTest, testObjectPackedArray)
592
1
{
593
1
    Vector<TestObject> rawArray{TestObject{0}, TestObject{2}, TestObject{4}, TestObject{6}, TestObject{8}};
594
1
    ArrayView<const TestObject> array(rawArray);
595
596
1
    static_assert(detail::is_packable_v<TestObject>, "shall be packable");
597
1
    static_assert(detail::is_packable_v<const TestObject>, "shall be packable");
598
599
    // maxBitNumber == 2
600
    // packingDescriptor 7 + firstElement 32 + 4 * (maxBitNumber 2 + 1)
601
1
    const BitSize packedBitSize = 51;
602
1
    ASSERT_EQ(packedBitSize, detail::bitSizeOfPacked<detail::ArrayType::NORMAL>(array));
603
604
1
    BitBuffer buffer(packedBitSize);
605
1
    BitStreamWriter writer(buffer);
606
1
    detail::writePacked<detail::ArrayType::NORMAL>(writer, array);
607
1
    ASSERT_EQ(packedBitSize, writer.getBitPosition());
608
609
1
    BitStreamReader reader(buffer);
610
1
    Vector<TestObject> readRawArray;
611
1
    detail::readPacked<detail::ArrayType::NORMAL>(reader, readRawArray, rawArray.size());
612
1
    ASSERT_EQ(packedBitSize, reader.getBitPosition());
613
1
    ASSERT_EQ(rawArray, readRawArray);
614
1
}
615
616
} // namespace zserio