Coverage Report

Created: 2023-12-13 14:58

src/zserio/ArrayTraits.h
Line
Count
Source
1
#ifndef ZSERIO_ARRAY_TRAITS_H_INC
2
#define ZSERIO_ARRAY_TRAITS_H_INC
3
4
#include <type_traits>
5
#include <string>
6
#include <vector>
7
8
#include "zserio/BitPositionUtil.h"
9
#include "zserio/BitSizeOfCalculator.h"
10
#include "zserio/BitStreamWriter.h"
11
#include "zserio/BitStreamReader.h"
12
#include "zserio/Enums.h"
13
#include "zserio/Traits.h"
14
#include "zserio/SizeConvertUtil.h"
15
#include "zserio/DeltaContext.h"
16
17
namespace zserio
18
{
19
20
namespace detail
21
{
22
23
template <typename T>
24
T read_bits(BitStreamReader& in, uint8_t numBits);
25
26
template <>
27
inline int8_t read_bits<int8_t>(BitStreamReader& in, uint8_t numBits)
28
496
{
29
496
    return static_cast<int8_t>(in.readSignedBits(numBits));
30
496
}
31
32
template <>
33
inline int16_t read_bits<int16_t>(BitStreamReader& in, uint8_t numBits)
34
504
{
35
504
    return static_cast<int16_t>(in.readSignedBits(numBits));
36
504
}
37
38
template <>
39
inline int32_t read_bits<int32_t>(BitStreamReader& in, uint8_t numBits)
40
312
{
41
312
    return in.readSignedBits(numBits);
42
312
}
43
44
template <>
45
inline int64_t read_bits<int64_t>(BitStreamReader& in, uint8_t numBits)
46
696
{
47
696
    return in.readSignedBits64(numBits);
48
696
}
49
50
template <>
51
inline uint8_t read_bits<uint8_t>(BitStreamReader& in, uint8_t numBits)
52
1.23k
{
53
1.23k
    return static_cast<uint8_t>(in.readBits(numBits));
54
1.23k
}
55
56
template <>
57
inline uint16_t read_bits<uint16_t>(BitStreamReader& in, uint8_t numBits)
58
312
{
59
312
    return static_cast<uint16_t>(in.readBits(numBits));
60
312
}
61
62
template <>
63
inline uint32_t read_bits<uint32_t>(BitStreamReader& in, uint8_t numBits)
64
376
{
65
376
    return in.readBits(numBits);
66
376
}
67
68
template <>
69
inline uint64_t read_bits<uint64_t>(BitStreamReader& in, uint8_t numBits)
70
632
{
71
632
    return in.readBits64(numBits);
72
632
}
73
74
template <typename T>
75
void write_bits(BitStreamWriter& out, T value, uint8_t numBits);
76
77
template <>
78
inline void write_bits<int8_t>(BitStreamWriter& out, int8_t value, uint8_t numBits)
79
496
{
80
496
    out.writeSignedBits(static_cast<int32_t>(value), numBits);
81
496
}
82
83
template <>
84
inline void write_bits<int16_t>(BitStreamWriter& out, int16_t value, uint8_t numBits)
85
504
{
86
504
    out.writeSignedBits(static_cast<int32_t>(value), numBits);
87
504
}
88
89
template <>
90
inline void write_bits<int32_t>(BitStreamWriter& out, int32_t value, uint8_t numBits)
91
312
{
92
312
    out.writeSignedBits(value, numBits);
93
312
}
94
95
template <>
96
inline void write_bits<int64_t>(BitStreamWriter& out, int64_t value, uint8_t numBits)
97
696
{
98
696
    out.writeSignedBits64(value, numBits);
99
696
}
100
101
template <>
102
inline void write_bits<uint8_t>(BitStreamWriter& out, uint8_t value, uint8_t numBits)
103
1.23k
{
104
1.23k
    out.writeBits(static_cast<uint32_t>(value), numBits);
105
1.23k
}
106
107
template <>
108
inline void write_bits<uint16_t>(BitStreamWriter& out, uint16_t value, uint8_t numBits)
109
312
{
110
312
    out.writeBits(static_cast<uint32_t>(value), numBits);
111
312
}
112
113
template <>
114
inline void write_bits<uint32_t>(BitStreamWriter& out, uint32_t value, uint8_t numBits)
115
376
{
116
376
    out.writeBits(value, numBits);
117
376
}
118
119
template <>
120
inline void write_bits<uint64_t>(BitStreamWriter& out, uint64_t value, uint8_t numBits)
121
632
{
122
632
    out.writeBits64(value, numBits);
123
632
}
124
125
} // namespace detail
126
127
/**
128
 * Array traits for bit field Zserio types.
129
 *
130
 * These traits are used for all fixed bit fields (int:N or bit:N) or for dynamic bit fields which
131
 * have constant bit size available during generation (int<N> or bit<N>).
132
 */
133
template <typename T, uint8_t NUM_BITS>
134
class BitFieldArrayTraits
135
{
136
public:
137
    /** Element type. */
138
    using ElementType = T;
139
140
    /**
141
     * Calculates bit size of the array element.
142
     *
143
     * \return Bit size of the array element.
144
     */
145
    static size_t bitSizeOf()
146
7.75k
    {
147
7.75k
        return NUM_BITS;
148
7.75k
    }
149
150
    /**
151
     * Calculates bit size of the array element.
152
     *
153
     * \return Bit size of the array element.
154
     */
155
    static size_t bitSizeOf(ElementType)
156
7.48k
    {
157
7.48k
        return bitSizeOf();
158
7.48k
    }
159
160
    /**
161
     * Calculates bit size of the array element.
162
     *
163
     * \return Bit size of the array element.
164
     */
165
    static size_t bitSizeOf(size_t, ElementType)
166
    {
167
        return bitSizeOf();
168
    }
169
170
    /**
171
     * Initializes indexed offsets of the single array element.
172
     *
173
     * \param bitPosition Current bit position.
174
     *
175
     * \return Updated bit position which points to the first bit after the array element.
176
     */
177
    static size_t initializeOffsets(size_t bitPosition, ElementType)
178
768
    {
179
768
        return bitPosition + NUM_BITS;
180
768
    }
181
182
    /**
183
     * Reads the single array element.
184
     *
185
     * \param in Bit stream reader.
186
     *
187
     * \return Read element.
188
     */
189
    static ElementType read(BitStreamReader& in, size_t = 0)
190
1.92k
    {
191
1.92k
        return detail::read_bits<T>(in, NUM_BITS);
192
1.92k
    }
193
194
    /**
195
     * Writes the single array element.
196
     *
197
     * \param out Bit stream writer to use.
198
     * \param element Element to write.
199
     */
200
    static void write(BitStreamWriter& out, ElementType element)
201
1.92k
    {
202
1.92k
        detail::write_bits(out, element, NUM_BITS);
203
1.92k
    }
204
205
    /** Determines whether the bit size of the single element is constant. */
206
    static constexpr bool IS_BITSIZEOF_CONSTANT = true;
207
};
208
209
/**
210
 * Array traits for dynamic bit field Zserio types with dynamic bit size (int<bitSize> or bit<bitSize>).
211
 *
212
 * Used for dynamic bit fields with length known at compile time - i.e. which depends on a constant expression
213
 * and doesn't need an owner.
214
 */
215
template <typename T, typename ELEMENT_BIT_SIZE, typename = void>
216
class DynamicBitFieldArrayTraits
217
{
218
public:
219
    /** Element type. */
220
    using ElementType = T;
221
222
    /**
223
     * Calculates bit size of the array element.
224
     *
225
     * \return Bit size of the array element.
226
     */
227
    static size_t bitSizeOf()
228
1.47k
    {
229
1.47k
        return ELEMENT_BIT_SIZE::get();
230
1.47k
    }
231
232
    /**
233
     * Calculates bit size of the array element.
234
     *
235
     * \return Bit size of the array element.
236
     */
237
    static size_t bitSizeOf(ElementType)
238
960
    {
239
960
        return bitSizeOf();
240
960
    }
241
242
    /**
243
     * Calculates bit size of the array element.
244
     *
245
     * \return Bit size of the array element.
246
     */
247
    static size_t bitSizeOf(size_t, ElementType)
248
    {
249
        return bitSizeOf();
250
    }
251
252
    /**
253
     * Initializes indexed offsets of the single array element.
254
     *
255
     * \param bitPosition Current bit position.
256
     *
257
     * \return Updated bit position which points to the first bit after the array element.
258
     */
259
    static size_t initializeOffsets(size_t bitPosition, ElementType)
260
384
    {
261
384
        return bitPosition + bitSizeOf();
262
384
    }
263
264
    /**
265
     * Reads the single array element.
266
     *
267
     * \param in Bit stream reader.
268
     *
269
     * \return Read element.
270
     */
271
    static ElementType read(BitStreamReader& in, size_t = 0)
272
576
    {
273
576
        return detail::read_bits<T>(in, ELEMENT_BIT_SIZE::get());
274
576
    }
275
276
    /**
277
     * Writes the single array element.
278
     *
279
     * \param out Bit stream writer to use.
280
     * \param element Element to write.
281
     */
282
    static void write(BitStreamWriter& out, ElementType element)
283
576
    {
284
576
        detail::write_bits(out, element, ELEMENT_BIT_SIZE::get());
285
576
    }
286
287
    /** Determines whether the bit size of the single element is constant. */
288
    static constexpr bool IS_BITSIZEOF_CONSTANT = true;
289
};
290
291
/**
292
 * Array traits for dynamic bit field Zserio types with dynamic bit size (int<bitSize> or bit<bitSize>).
293
 *
294
 * Specialization for dynamic bit fields which length depends on an arbitrary expression - i.e. which may
295
 * need an owner.
296
 */
297
template <typename T, typename ELEMENT_BIT_SIZE>
298
class DynamicBitFieldArrayTraits<T, ELEMENT_BIT_SIZE,
299
        typename std::enable_if<has_owner_type<ELEMENT_BIT_SIZE>::value>::type>
300
{
301
public:
302
    /** Element type. */
303
    using ElementType = T;
304
305
    /** Typedef for the array's owner type. */
306
    using OwnerType = typename ELEMENT_BIT_SIZE::OwnerType;
307
308
    /**
309
     * Calculates bit size of the array element.
310
     *
311
     * \param owner Owner of the current array.
312
     *
313
     * \return Bit size of the array element.
314
     */
315
    static size_t bitSizeOf(const OwnerType& owner)
316
1.81k
    {
317
1.81k
        return ELEMENT_BIT_SIZE::get(owner);
318
1.81k
    }
319
320
    /**
321
     * Calculates bit size of the array element.
322
     *
323
     * \param owner Owner of the current array.
324
     *
325
     * \return Bit size of the array element.
326
     */
327
    static size_t bitSizeOf(const OwnerType& owner, ElementType)
328
960
    {
329
960
        return bitSizeOf(owner);
330
960
    }
331
332
    /**
333
     * Calculates bit size of the array element.
334
     *
335
     * \param owner Owner of the current array.
336
     *
337
     * \return Bit size of the array element.
338
     */
339
    static size_t bitSizeOf(const OwnerType& owner, size_t, ElementType)
340
    {
341
        return bitSizeOf(owner);
342
    }
343
344
    /**
345
     * Initializes indexed offsets of the single array element.
346
     *
347
     * \param owner Owner of the current array.
348
     * \param bitPosition Current bit position.
349
     *
350
     * \return Updated bit position which points to the first bit after the array element.
351
     */
352
    static size_t initializeOffsets(const OwnerType& owner, size_t bitPosition, ElementType)
353
624
    {
354
624
        return bitPosition + bitSizeOf(owner);
355
624
    }
356
357
    /**
358
     * Reads the single array element.
359
     *
360
     * \param owner Owner of the current array.
361
     * \param in Bit stream reader.
362
     *
363
     * \return Read element.
364
     */
365
    static ElementType read(const OwnerType& owner, BitStreamReader& in, size_t = 0)
366
816
    {
367
816
        return detail::read_bits<T>(in, ELEMENT_BIT_SIZE::get(owner));
368
816
    }
369
370
    /**
371
     * Writes the single array element.
372
     *
373
     * \param owner Owner of the current array.
374
     * \param out Bit stream writer to use.
375
     * \param element Element to write.
376
     */
377
    static void write(const OwnerType& owner, BitStreamWriter& out, ElementType element)
378
816
    {
379
816
        detail::write_bits(out, element, ELEMENT_BIT_SIZE::get(owner));
380
816
    }
381
382
    /** Determines whether the bit size of the single element is constant. */
383
    static constexpr bool IS_BITSIZEOF_CONSTANT = true;
384
};
385
386
/**
387
 * Array traits for fixed integer Zserio types (int16, uint16, int32, uint32, etc...).
388
 */
389
template <typename T>
390
struct StdIntArrayTraits
391
{
392
    /** Element type. */
393
    using ElementType = T;
394
395
    /**
396
     * Calculates bit size of the array element.
397
     *
398
     * \return Bit size of the array element.
399
     */
400
    static size_t bitSizeOf()
401
4.15k
    {
402
4.15k
        return NUM_BITS;
403
4.15k
    }
404
405
    /**
406
     * Calculates bit size of the array element.
407
     *
408
     * \return Bit size of the array element.
409
     */
410
    static size_t bitSizeOf(ElementType)
411
3.74k
    {
412
3.74k
        return bitSizeOf();
413
3.74k
    }
414
415
    /**
416
     * Calculates bit size of the array element.
417
     *
418
     * \return Bit size of the array element.
419
     */
420
    static size_t bitSizeOf(size_t, ElementType)
421
    {
422
        return bitSizeOf();
423
    }
424
425
    /**
426
     * Initializes indexed offsets of the single array element.
427
     *
428
     * \param bitPosition Current bit position.
429
     *
430
     * \return Updated bit position which points to the first bit after the array element.
431
     */
432
    static size_t initializeOffsets(size_t bitPosition, ElementType)
433
960
    {
434
960
        return bitPosition + NUM_BITS;
435
960
    }
436
437
    /**
438
     * Reads the single array element.
439
     *
440
     * \param in Bit stream reader.
441
     *
442
     * \return Read element.
443
     */
444
    static ElementType read(BitStreamReader& in, size_t = 0)
445
1.24k
    {
446
1.24k
        return detail::read_bits<T>(in, NUM_BITS);
447
1.24k
    }
448
449
    /**
450
     * Writes the single array element.
451
     *
452
     * \param out Bit stream writer to use.
453
     * \param element Element to write.
454
     */
455
    static void write(BitStreamWriter& out, ElementType element)
456
1.24k
    {
457
1.24k
        detail::write_bits(out, element, NUM_BITS);
458
1.24k
    }
459
460
    /** Determines whether the bit size of the single element is constant. */
461
    static constexpr bool IS_BITSIZEOF_CONSTANT = true;
462
463
private:
464
    static constexpr uint8_t NUM_BITS = sizeof(T) * 8;
465
};
466
467
/**
468
 * Array traits for variable integer Zserio types (varint16, varuint16, etc...).
469
 */
470
template <typename T>
471
struct VarIntNNArrayTraits;
472
473
/**
474
 * Array traits specialization for Zserio varint16 type.
475
 */
476
template <>
477
struct VarIntNNArrayTraits<int16_t>
478
{
479
    /** Element type. */
480
    using ElementType = int16_t;
481
482
    /**
483
     * Calculates bit size of the array element.
484
     *
485
     * \param element Element to use for calculation.
486
     *
487
     * \return Bit size of the array element.
488
     */
489
    static size_t bitSizeOf(ElementType element)
490
128
    {
491
128
        return zserio::bitSizeOfVarInt16(element);
492
128
    }
493
494
    /**
495
     * Calculates bit size of the array element.
496
     *
497
     * \param element Element to use for calculation.
498
     *
499
     * \return Bit size of the array element.
500
     */
501
    static size_t bitSizeOf(size_t, ElementType element)
502
128
    {
503
128
        return bitSizeOf(element);
504
128
    }
505
506
    /**
507
     * Initializes indexed offsets of the single array element.
508
     *
509
     * \param bitPosition Current bit position.
510
     * \param element Element to use for calculation.
511
     *
512
     * \return Updated bit position which points to the first bit after the array element.
513
     */
514
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
515
64
    {
516
64
        return bitPosition + bitSizeOf(bitPosition, element);
517
64
    }
518
519
    /**
520
     * Reads the single array element.
521
     *
522
     * \param in Bit stream reader.
523
     *
524
     * \return Read element.
525
     */
526
    static ElementType read(BitStreamReader& in, size_t = 0)
527
64
    {
528
64
        return in.readVarInt16();
529
64
    }
530
531
    /**
532
     * Writes the single array element.
533
     *
534
     * \param out Bit stream writer to use.
535
     * \param element Element to write.
536
     */
537
    static void write(BitStreamWriter& out, ElementType element)
538
64
    {
539
64
        out.writeVarInt16(element);
540
64
    }
541
542
    /** Determines whether the bit size of the single element is constant. */
543
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
544
};
545
546
/**
547
 * Array traits specialization for Zserio varint32 type.
548
 */
549
template <>
550
struct VarIntNNArrayTraits<int32_t>
551
{
552
    /** Element type. */
553
    using ElementType = int32_t;
554
555
    /**
556
     * Calculates bit size of the array element.
557
     *
558
     * \param element Element to use for calculation.
559
     *
560
     * \return Bit size of the array element.
561
     */
562
    static size_t bitSizeOf(ElementType element)
563
256
    {
564
256
        return zserio::bitSizeOfVarInt32(element);
565
256
    }
566
567
    /**
568
     * Calculates bit size of the array element.
569
     *
570
     * \param element Element to use for calculation.
571
     *
572
     * \return Bit size of the array element.
573
     */
574
    static size_t bitSizeOf(size_t, ElementType element)
575
256
    {
576
256
        return bitSizeOf(element);
577
256
    }
578
579
    /**
580
     * Initializes indexed offsets of the single array element.
581
     *
582
     * \param bitPosition Current bit position.
583
     * \param element Element to use for calculation.
584
     *
585
     * \return Updated bit position which points to the first bit after the array element.
586
     */
587
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
588
128
    {
589
128
        return bitPosition + bitSizeOf(bitPosition, element);
590
128
    }
591
592
    /**
593
     * Reads the single array element.
594
     *
595
     * \param in Bit stream reader.
596
     *
597
     * \return Read element.
598
     */
599
    static ElementType read(BitStreamReader& in, size_t = 0)
600
128
    {
601
128
        return in.readVarInt32();
602
128
    }
603
604
    /**
605
     * Writes the single array element.
606
     *
607
     * \param out Bit stream writer to use.
608
     * \param element Element to write.
609
     */
610
    static void write(BitStreamWriter& out, ElementType element)
611
128
    {
612
128
        out.writeVarInt32(element);
613
128
    }
614
615
    /** Determines whether the bit size of the single element is constant. */
616
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
617
};
618
619
/**
620
 * Array traits specialization for Zserio varint64 type.
621
 */
622
template <>
623
struct VarIntNNArrayTraits<int64_t>
624
{
625
    /** Element type. */
626
    using ElementType = int64_t;
627
628
    /**
629
     * Calculates bit size of the array element.
630
     *
631
     * \param element Element to use for calculation.
632
     *
633
     * \return Bit size of the array element.
634
     */
635
    static size_t bitSizeOf(ElementType element)
636
512
    {
637
512
        return zserio::bitSizeOfVarInt64(element);
638
512
    }
639
640
    /**
641
     * Calculates bit size of the array element.
642
     *
643
     * \param element Element to use for calculation.
644
     *
645
     * \return Bit size of the array element.
646
     */
647
    static size_t bitSizeOf(size_t, ElementType element)
648
512
    {
649
512
        return bitSizeOf(element);
650
512
    }
651
652
    /**
653
     * Initializes indexed offsets of the single array element.
654
     *
655
     * \param bitPosition Current bit position.
656
     * \param element Element to use for calculation.
657
     *
658
     * \return Updated bit position which points to the first bit after the array element.
659
     */
660
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
661
256
    {
662
256
        return bitPosition + bitSizeOf(bitPosition, element);
663
256
    }
664
665
    /**
666
     * Reads the single array element.
667
     *
668
     * \param in Bit stream reader.
669
     *
670
     * \return Read element.
671
     */
672
    static ElementType read(BitStreamReader& in, size_t = 0)
673
256
    {
674
256
        return in.readVarInt64();
675
256
    }
676
677
    /**
678
     * Writes the single array element.
679
     *
680
     * \param out Bit stream writer to use.
681
     * \param element Element to write.
682
     */
683
    static void write(BitStreamWriter& out, ElementType element)
684
256
    {
685
256
        out.writeVarInt64(element);
686
256
    }
687
688
    /** Determines whether the bit size of the single element is constant. */
689
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
690
};
691
692
/**
693
 * Array traits specialization for Zserio varuint16 type.
694
 */
695
template <>
696
struct VarIntNNArrayTraits<uint16_t>
697
{
698
    /** Element type. */
699
    using ElementType = uint16_t;
700
701
    /**
702
     * Calculates bit size of the array element.
703
     *
704
     * \param element Element to use for calculation.
705
     *
706
     * \return Bit size of the array element.
707
     */
708
    static size_t bitSizeOf(ElementType element)
709
128
    {
710
128
        return zserio::bitSizeOfVarUInt16(element);
711
128
    }
712
713
    /**
714
     * Calculates bit size of the array element.
715
     *
716
     * \param element Element to use for calculation.
717
     *
718
     * \return Bit size of the array element.
719
     */
720
    static size_t bitSizeOf(size_t, ElementType element)
721
128
    {
722
128
        return bitSizeOf(element);
723
128
    }
724
725
    /**
726
     * Initializes indexed offsets of the single array element.
727
     *
728
     * \param bitPosition Current bit position.
729
     * \param element Element to use for calculation.
730
     *
731
     * \return Updated bit position which points to the first bit after the array element.
732
     */
733
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
734
64
    {
735
64
        return bitPosition + bitSizeOf(bitPosition, element);
736
64
    }
737
738
    /**
739
     * Reads the single array element.
740
     *
741
     * \param in Bit stream reader.
742
     *
743
     * \return Read element.
744
     */
745
    static ElementType read(BitStreamReader& in, size_t = 0)
746
64
    {
747
64
        return in.readVarUInt16();
748
64
    }
749
750
    /**
751
     * Writes the single array element.
752
     *
753
     * \param out Bit stream writer to use.
754
     * \param element Element to write.
755
     */
756
    static void write(BitStreamWriter& out, ElementType element)
757
64
    {
758
64
        out.writeVarUInt16(element);
759
64
    }
760
761
    /** Determines whether the bit size of the single element is constant. */
762
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
763
};
764
765
/**
766
 * Array traits specialization for Zserio varuint32 type.
767
 */
768
template <>
769
struct VarIntNNArrayTraits<uint32_t>
770
{
771
    /** Element type. */
772
    using ElementType = uint32_t;
773
774
    /**
775
     * Calculates bit size of the array element.
776
     *
777
     * \param element Element to use for calculation.
778
     *
779
     * \return Bit size of the array element.
780
     */
781
    static size_t bitSizeOf(ElementType element)
782
256
    {
783
256
        return zserio::bitSizeOfVarUInt32(element);
784
256
    }
785
786
    /**
787
     * Calculates bit size of the array element.
788
     *
789
     * \param element Element to use for calculation.
790
     *
791
     * \return Bit size of the array element.
792
     */
793
    static size_t bitSizeOf(size_t, ElementType element)
794
256
    {
795
256
        return bitSizeOf(element);
796
256
    }
797
798
    /**
799
     * Initializes indexed offsets of the single array element.
800
     *
801
     * \param bitPosition Current bit position.
802
     * \param element Element to use for calculation.
803
     *
804
     * \return Updated bit position which points to the first bit after the array element.
805
     */
806
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
807
128
    {
808
128
        return bitPosition + bitSizeOf(bitPosition, element);
809
128
    }
810
811
    /**
812
     * Reads the single array element.
813
     *
814
     * \param in Bit stream reader.
815
     *
816
     * \return Read element.
817
     */
818
    static ElementType read(BitStreamReader& in, size_t = 0)
819
128
    {
820
128
        return in.readVarUInt32();
821
128
    }
822
823
    /**
824
     * Writes the single array element.
825
     *
826
     * \param out Bit stream writer to use.
827
     * \param element Element to write.
828
     */
829
    static void write(BitStreamWriter& out, ElementType element)
830
128
    {
831
128
        out.writeVarUInt32(element);
832
128
    }
833
834
    /** Determines whether the bit size of the single element is constant. */
835
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
836
};
837
838
/**
839
 * Array traits specialization for Zserio varuint64 type.
840
 */
841
template <>
842
struct VarIntNNArrayTraits<uint64_t>
843
{
844
    /** Element type. */
845
    using ElementType = uint64_t;
846
847
    /**
848
     * Calculates bit size of the array element.
849
     *
850
     * \param element Element to use for calculation.
851
     *
852
     * \return Bit size of the array element.
853
     */
854
    static size_t bitSizeOf(ElementType element)
855
2.91k
    {
856
2.91k
        return zserio::bitSizeOfVarUInt64(element);
857
2.91k
    }
858
859
    /**
860
     * Calculates bit size of the array element.
861
     *
862
     * \param element Element to use for calculation.
863
     *
864
     * \return Bit size of the array element.
865
     */
866
    static size_t bitSizeOf(size_t, ElementType element)
867
512
    {
868
512
        return bitSizeOf(element);
869
512
    }
870
871
    /**
872
     * Initializes indexed offsets of the single array element.
873
     *
874
     * \param bitPosition Current bit position.
875
     * \param element Element to use for calculation.
876
     *
877
     * \return Updated bit position which points to the first bit after the array element.
878
     */
879
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
880
256
    {
881
256
        return bitPosition + bitSizeOf(bitPosition, element);
882
256
    }
883
884
    /**
885
     * Reads the single array element.
886
     *
887
     * \param in Bit stream reader.
888
     *
889
     * \return Read element.
890
     */
891
    static ElementType read(BitStreamReader& in, size_t = 0)
892
736
    {
893
736
        return in.readVarUInt64();
894
736
    }
895
896
    /**
897
     * Writes the single array element.
898
     *
899
     * \param out Bit stream writer to use.
900
     * \param element Element to write.
901
     */
902
    static void write(BitStreamWriter& out, ElementType element)
903
736
    {
904
736
        out.writeVarUInt64(element);
905
736
    }
906
907
    /** Determines whether the bit size of the single element is constant. */
908
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
909
};
910
911
/**
912
 * Array traits for big variable integer Zserio types (varint, varuint).
913
 */
914
template <typename T>
915
struct VarIntArrayTraits;
916
917
/**
918
 * Array traits specialization for Zserio varint type.
919
 */
920
template <>
921
struct VarIntArrayTraits<int64_t>
922
{
923
    /** Element type. */
924
    using ElementType = int64_t;
925
926
    /**
927
     * Calculates bit size of the array element.
928
     *
929
     * \param element Element to use for calculation.
930
     *
931
     * \return Bit size of the array element.
932
     */
933
    static size_t bitSizeOf(ElementType element)
934
1.40k
    {
935
1.40k
        return zserio::bitSizeOfVarInt(element);
936
1.40k
    }
937
938
    /**
939
     * Calculates bit size of the array element.
940
     *
941
     * \param element Element to use for calculation.
942
     *
943
     * \return Bit size of the array element.
944
     */
945
    static size_t bitSizeOf(size_t, ElementType element)
946
1.40k
    {
947
1.40k
        return bitSizeOf(element);
948
1.40k
    }
949
950
    /**
951
     * Initializes indexed offsets of the single array element.
952
     *
953
     * \param bitPosition Current bit position.
954
     * \param element Element to use for calculation.
955
     *
956
     * \return Updated bit position which points to the first bit after the array element.
957
     */
958
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
959
704
    {
960
704
        return bitPosition + bitSizeOf(bitPosition, element);
961
704
    }
962
963
    /**
964
     * Reads the single array element.
965
     *
966
     * \param in Bit stream reader.
967
     *
968
     * \return Read element.
969
     */
970
    static ElementType read(BitStreamReader& in, size_t = 0)
971
704
    {
972
704
        return in.readVarInt();
973
704
    }
974
975
    /**
976
     * Writes the single array element.
977
     *
978
     * \param out Bit stream writer to use.
979
     * \param element Element to write.
980
     */
981
    static void write(BitStreamWriter& out, ElementType element)
982
704
    {
983
704
        out.writeVarInt(element);
984
704
    }
985
986
    /** Determines whether the bit size of the single element is constant. */
987
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
988
};
989
990
/**
991
 * Array traits specialization for Zserio varuint type.
992
 */
993
template <>
994
struct VarIntArrayTraits<uint64_t>
995
{
996
    /** Element type. */
997
    using ElementType = uint64_t;
998
999
    /**
1000
     * Calculates bit size of the array element.
1001
     *
1002
     * \param element Element to use for calculation.
1003
     *
1004
     * \return Bit size of the array element.
1005
     */
1006
    static size_t bitSizeOf(ElementType element)
1007
704
    {
1008
704
        return zserio::bitSizeOfVarUInt(element);
1009
704
    }
1010
1011
    /**
1012
     * Calculates bit size of the array element.
1013
     *
1014
     * \param element Element to use for calculation.
1015
     *
1016
     * \return Bit size of the array element.
1017
     */
1018
    static size_t bitSizeOf(size_t, ElementType element)
1019
704
    {
1020
704
        return bitSizeOf(element);
1021
704
    }
1022
1023
    /**
1024
     * Initializes indexed offsets of the single array element.
1025
     *
1026
     * \param bitPosition Current bit position.
1027
     * \param element Element to use for calculation.
1028
     *
1029
     * \return Updated bit position which points to the first bit after the array element.
1030
     */
1031
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
1032
352
    {
1033
352
        return bitPosition + bitSizeOf(bitPosition, element);
1034
352
    }
1035
1036
    /**
1037
     * Reads the single array element.
1038
     *
1039
     * \param in Bit stream reader.
1040
     *
1041
     * \return Read element.
1042
     */
1043
    static ElementType read(BitStreamReader& in, size_t = 0)
1044
352
    {
1045
352
        return in.readVarUInt();
1046
352
    }
1047
1048
    /**
1049
     * Writes the single array element.
1050
     *
1051
     * \param out Bit stream writer to use.
1052
     * \param element Element to write.
1053
     */
1054
    static void write(BitStreamWriter& out, ElementType element)
1055
352
    {
1056
352
        out.writeVarUInt(element);
1057
352
    }
1058
1059
    /** Determines whether the bit size of the single element is constant. */
1060
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
1061
};
1062
1063
/**
1064
 * Array traits specialization for Zserio varsize type.
1065
 */
1066
struct VarSizeArrayTraits
1067
{
1068
    /** Element type. */
1069
    using ElementType = uint32_t;
1070
1071
    /**
1072
     * Calculates bit size of the array element.
1073
     *
1074
     * \param element Element to use for calculation.
1075
     *
1076
     * \return Bit size of the array element.
1077
     */
1078
    static size_t bitSizeOf(ElementType element)
1079
1.12k
    {
1080
1.12k
        return zserio::bitSizeOfVarSize(element);
1081
1.12k
    }
1082
1083
    /**
1084
     * Calculates bit size of the array element.
1085
     *
1086
     * \param element Element to use for calculation.
1087
     *
1088
     * \return Bit size of the array element.
1089
     */
1090
    static size_t bitSizeOf(size_t, ElementType element)
1091
320
    {
1092
320
        return bitSizeOf(element);
1093
320
    }
1094
1095
    /**
1096
     * Initializes indexed offsets of the single array element.
1097
     *
1098
     * \param bitPosition Current bit position.
1099
     * \param element Element to use for calculation.
1100
     *
1101
     * \return Updated bit position which points to the first bit after the array element.
1102
     */
1103
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
1104
160
    {
1105
160
        return bitPosition + bitSizeOf(bitPosition, element);
1106
160
    }
1107
1108
    /**
1109
     * Reads the single array element.
1110
     *
1111
     * \param in Bit stream reader.
1112
     *
1113
     * \return Read element.
1114
     */
1115
    static ElementType read(BitStreamReader& in, size_t = 0)
1116
320
    {
1117
320
        return in.readVarSize();
1118
320
    }
1119
1120
    /**
1121
     * Writes the single array element.
1122
     *
1123
     * \param out Bit stream writer to use.
1124
     * \param element Element to write
1125
     */
1126
    static void write(BitStreamWriter& out, ElementType element)
1127
320
    {
1128
320
        out.writeVarSize(element);
1129
320
    }
1130
1131
    /** Determines whether the bit size of the single element is constant. */
1132
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
1133
};
1134
1135
/**
1136
 * Array traits for Zserio float16 type.
1137
 */
1138
struct Float16ArrayTraits
1139
{
1140
    /** Element type. */
1141
    using ElementType = float;
1142
1143
    /**
1144
     * Calculates bit size of the array element.
1145
     *
1146
     * \return Bit size of the array element.
1147
     */
1148
    static size_t bitSizeOf()
1149
178
    {
1150
178
        return 16;
1151
178
    }
1152
1153
    /**
1154
     * Calculates bit size of the array element.
1155
     *
1156
     * \return Bit size of the array element.
1157
     */
1158
    static size_t bitSizeOf(size_t, ElementType)
1159
120
    {
1160
120
        return bitSizeOf();
1161
120
    }
1162
1163
    /**
1164
     * Initializes indexed offsets of the single array element.
1165
     *
1166
     * \param bitPosition Current bit position.
1167
     * \param element Element to use for calculation.
1168
     *
1169
     * \return Updated bit position which points to the first bit after the array element.
1170
     */
1171
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
1172
120
    {
1173
120
        return bitPosition + bitSizeOf(bitPosition, element);
1174
120
    }
1175
1176
    /**
1177
     * Reads the single array element.
1178
     *
1179
     * \param in Bit stream reader.
1180
     *
1181
     * \return Read element.
1182
     */
1183
    static ElementType read(BitStreamReader& in, size_t = 0)
1184
120
    {
1185
120
        return in.readFloat16();
1186
120
    }
1187
1188
    /**
1189
     * Writes the single array element.
1190
     *
1191
     * \param out Bit stream writer to use.
1192
     * \param element Element to write.
1193
     */
1194
    static void write(BitStreamWriter& out, ElementType element)
1195
120
    {
1196
120
        out.writeFloat16(element);
1197
120
    }
1198
1199
    /** Determines whether the bit size of the single element is constant. */
1200
    static constexpr bool IS_BITSIZEOF_CONSTANT = true;
1201
};
1202
1203
/**
1204
 * Array traits for Zserio float32 type.
1205
 */
1206
struct Float32ArrayTraits
1207
{
1208
    /** Element type. */
1209
    using ElementType = float;
1210
1211
    /**
1212
     * Calculates bit size of the array element.
1213
     *
1214
     * \return Bit size of the array element.
1215
     */
1216
    static size_t bitSizeOf()
1217
178
    {
1218
178
        return 32;
1219
178
    }
1220
1221
    /**
1222
     * Calculates bit size of the array element.
1223
     *
1224
     * \return Bit size of the array element.
1225
     */
1226
    static size_t bitSizeOf(size_t, ElementType)
1227
120
    {
1228
120
        return bitSizeOf();
1229
120
    }
1230
1231
    /**
1232
     * Initializes indexed offsets of the single array element.
1233
     *
1234
     * \param bitPosition Current bit position.
1235
     * \param element Element to use for calculation.
1236
     *
1237
     * \return Updated bit position which points to the first bit after the array element.
1238
     */
1239
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
1240
120
    {
1241
120
        return bitPosition + bitSizeOf(bitPosition, element);
1242
120
    }
1243
1244
    /**
1245
     * Reads the single array element.
1246
     *
1247
     * \param in Bit stream reader.
1248
     *
1249
     * \return Read element.
1250
     */
1251
    static ElementType read(BitStreamReader& in, size_t = 0)
1252
120
    {
1253
120
        return in.readFloat32();
1254
120
    }
1255
1256
    /**
1257
     * Writes the single array element.
1258
     *
1259
     * \param out Bit stream writer to use.
1260
     * \param element Element to write.
1261
     */
1262
    static void write(BitStreamWriter& out, ElementType element)
1263
120
    {
1264
120
        out.writeFloat32(element);
1265
120
    }
1266
1267
    /** Determines whether the bit size of the single element is constant. */
1268
    static constexpr bool IS_BITSIZEOF_CONSTANT = true;
1269
};
1270
1271
/**
1272
 * Array traits for Zserio float64 type.
1273
 */
1274
struct Float64ArrayTraits
1275
{
1276
    /** Element type. */
1277
    using ElementType = double;
1278
1279
    /**
1280
     * Calculates bit size of the array element.
1281
     *
1282
     * \return Bit size of the array element.
1283
     */
1284
    static size_t bitSizeOf()
1285
178
    {
1286
178
        return 64;
1287
178
    }
1288
1289
    /**
1290
     * Calculates bit size of the array element.
1291
     *
1292
     * \return Bit size of the array element.
1293
     */
1294
    static size_t bitSizeOf(size_t, ElementType)
1295
120
    {
1296
120
        return bitSizeOf();
1297
120
    }
1298
1299
    /**
1300
     * Initializes indexed offsets of the single array element.
1301
     *
1302
     * \param bitPosition Current bit position.
1303
     * \param element Element to use for calculation.
1304
     *
1305
     * \return Updated bit position which points to the first bit after the array element.
1306
     */
1307
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
1308
120
    {
1309
120
        return bitPosition + bitSizeOf(bitPosition, element);
1310
120
    }
1311
1312
    /**
1313
     * Reads the single array element.
1314
     *
1315
     * \param in Bit stream reader.
1316
     *
1317
     * \return Read element.
1318
     */
1319
    static ElementType read(BitStreamReader& in, size_t = 0)
1320
120
    {
1321
120
        return in.readFloat64();
1322
120
    }
1323
1324
    /**
1325
     * Writes the single array element.
1326
     *
1327
     * \param out Bit stream writer to use.
1328
     * \param element Element to write.
1329
     */
1330
    static void write(BitStreamWriter& out, ElementType element)
1331
120
    {
1332
120
        out.writeFloat64(element);
1333
120
    }
1334
1335
    /** Determines whether the bit size of the single element is constant. */
1336
    static constexpr bool IS_BITSIZEOF_CONSTANT = true;
1337
};
1338
1339
/**
1340
 * Array traits for Zserio bool type.
1341
 */
1342
struct BoolArrayTraits
1343
{
1344
    /** Element type. */
1345
    using ElementType = bool;
1346
1347
    /**
1348
     * Calculates bit size of the array element.
1349
     *
1350
     * \return Bit size of the array element.
1351
     */
1352
    static size_t bitSizeOf()
1353
98
    {
1354
98
        return 1;
1355
98
    }
1356
1357
    /**
1358
     * Calculates bit size of the array element.
1359
     *
1360
     * \return Bit size of the array element.
1361
     */
1362
    static size_t bitSizeOf(size_t, ElementType)
1363
64
    {
1364
64
        return bitSizeOf();
1365
64
    }
1366
1367
    /**
1368
     * Initializes indexed offsets of the single array element.
1369
     *
1370
     * \param bitPosition Current bit position.
1371
     * \param element Element to use for calculation.
1372
     *
1373
     * \return Updated bit position which points to the first bit after the array element.
1374
     */
1375
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
1376
64
    {
1377
64
        return bitPosition + bitSizeOf(bitPosition, element);
1378
64
    }
1379
1380
    /**
1381
     * Reads the single array element.
1382
     *
1383
     * \param in Bit stream reader.
1384
     *
1385
     * \return Read element.
1386
     */
1387
    static ElementType read(BitStreamReader& in, size_t = 0)
1388
64
    {
1389
64
        return in.readBool();
1390
64
    }
1391
1392
    /**
1393
     * Writes the single array element.
1394
     *
1395
     * \param out Bit stream writer to use.
1396
     * \param element Element to write.
1397
     */
1398
    static void write(BitStreamWriter& out, ElementType element)
1399
64
    {
1400
64
        out.writeBool(element);
1401
64
    }
1402
1403
    /** Determines whether the bit size of the single element is constant. */
1404
    static constexpr bool IS_BITSIZEOF_CONSTANT = true;
1405
};
1406
1407
/**
1408
 * Array traits for Zserio bytes type.
1409
 */
1410
template <template <typename> class ALLOC = std::allocator>
1411
struct BasicBytesArrayTraits
1412
{
1413
    /** ElementType */
1414
    using ElementType = zserio::vector<uint8_t, ALLOC<uint8_t>>;
1415
1416
    /** Allocator type. */
1417
    using allocator_type = typename ElementType::allocator_type;
1418
1419
    /**
1420
     * Calculates bit size of the array element.
1421
     *
1422
     * \param element Element to use for calculation.
1423
     *
1424
     * \return Bit size of the array element.
1425
     */
1426
    static size_t bitSizeOf(size_t, const ElementType& element)
1427
128
    {
1428
128
        return zserio::bitSizeOfBytes(element);
1429
128
    }
1430
1431
    /**
1432
     * Initializes indexed offsets of the single array element.
1433
     *
1434
     * \param bitPosition Current bit position.
1435
     * \param element Element to use for calculation.
1436
     *
1437
     * \return Updated bit position which points to the first bit after the array element.
1438
     */
1439
    static size_t initializeOffsets(size_t bitPosition, const ElementType& element)
1440
64
    {
1441
64
        return bitPosition + bitSizeOf(bitPosition, element);
1442
64
    }
1443
1444
    /**
1445
     * Reads the single array element.
1446
     *
1447
     * \param rawArray Raw array to use.
1448
     * \param in Bit stream reader.
1449
     */
1450
    template <typename RAW_ARRAY>
1451
    static void read(RAW_ARRAY& rawArray, BitStreamReader& in, size_t = 0)
1452
64
    {
1453
64
        rawArray.emplace_back(in.readBytes(rawArray.get_allocator()));
1454
64
    }
1455
1456
    /**
1457
     * Writes the single array element.
1458
     *
1459
     * \param out Bit stream writer to use.
1460
     * \param element Element to write.
1461
     */
1462
    static void write(BitStreamWriter& out, const ElementType& element)
1463
64
    {
1464
64
        out.writeBytes(element);
1465
64
    }
1466
1467
    /** Determines whether the bit size of the single element is constant. */
1468
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
1469
};
1470
1471
using BytesArrayTraits = BasicBytesArrayTraits<>;
1472
1473
/**
1474
 * Array traits for Zserio string type.
1475
 */
1476
template <template <typename> class ALLOC = std::allocator>
1477
struct BasicStringArrayTraits
1478
{
1479
    /** Element type. */
1480
    using ElementType = zserio::string<ALLOC<char>>;
1481
1482
    /** Allocator type. */
1483
    using allocator_type = typename ElementType::allocator_type;
1484
1485
    /**
1486
     * Calculates bit size of the array element.
1487
     *
1488
     * \param element Element to use for calculation.
1489
     *
1490
     * \return Bit size of the array element.
1491
     */
1492
    static size_t bitSizeOf(size_t, const ElementType& element)
1493
192
    {
1494
192
        return zserio::bitSizeOfString(element);
1495
192
    }
1496
1497
    /**
1498
     * Initializes indexed offsets of the single array element.
1499
     *
1500
     * \param bitPosition Current bit position.
1501
     * \param element Element to use for calculation.
1502
     *
1503
     * \return Updated bit position which points to the first bit after the array element.
1504
     */
1505
    static size_t initializeOffsets(size_t bitPosition, const ElementType& element)
1506
96
    {
1507
96
        return bitPosition + bitSizeOf(bitPosition, element);
1508
96
    }
1509
1510
    /**
1511
     * Reads the single array element.
1512
     *
1513
     * \param rawArray Raw array to use.
1514
     * \param in Bit stream reader.
1515
     */
1516
    template <typename RAW_ARRAY>
1517
    static void read(RAW_ARRAY& rawArray, BitStreamReader& in, size_t = 0)
1518
96
    {
1519
96
        rawArray.emplace_back(in.readString(rawArray.get_allocator()));
1520
96
    }
1521
1522
    /**
1523
     * Writes the single array element.
1524
     *
1525
     * \param out Bit stream writer to use.
1526
     * \param element Element to write.
1527
     */
1528
    static void write(BitStreamWriter& out, const ElementType& element)
1529
96
    {
1530
96
        out.writeString(element);
1531
96
    }
1532
1533
    /** Determines whether the bit size of the single element is constant. */
1534
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
1535
};
1536
1537
using StringArrayTraits = BasicStringArrayTraits<>;
1538
1539
/**
1540
 * Array traits for Zserio extern bit buffer type.
1541
 */
1542
template <template <typename> class ALLOC = std::allocator>
1543
struct BasicBitBufferArrayTraits
1544
{
1545
    /** Element type. */
1546
    using ElementType = BasicBitBuffer<ALLOC<uint8_t>>;
1547
1548
    /** Allocator type. */
1549
    using allocator_type = typename ElementType::allocator_type;
1550
1551
    /**
1552
     * Calculates bit size of the array element.
1553
     *
1554
     * \param element Element to use for calculation.
1555
     *
1556
     * \return Bit size of the array element.
1557
     */
1558
    static size_t bitSizeOf(size_t, const ElementType& element)
1559
192
    {
1560
192
        return zserio::bitSizeOfBitBuffer(element);
1561
192
    }
1562
1563
    /**
1564
     * Initializes indexed offsets of the single array element.
1565
     *
1566
     * \param bitPosition Current bit position.
1567
     * \param element Element to use for calculation.
1568
     *
1569
     * \return Updated bit position which points to the first bit after the array element.
1570
     */
1571
    static size_t initializeOffsets(size_t bitPosition, const ElementType& element)
1572
96
    {
1573
96
        return bitPosition + bitSizeOf(bitPosition, element);
1574
96
    }
1575
1576
    /**
1577
     * Reads the single array element.
1578
     *
1579
     * \param rawArray Raw array to use.
1580
     * \param in Bit stream reader.
1581
     */
1582
    template <typename RAW_ARRAY>
1583
    static void read(RAW_ARRAY& rawArray, BitStreamReader& in, size_t = 0)
1584
96
    {
1585
96
        rawArray.emplace_back(in.readBitBuffer(rawArray.get_allocator()));
1586
96
    }
1587
1588
    /**
1589
     * Writes the single array element.
1590
     *
1591
     * \param out Bit stream writer to use.
1592
     * \param element Element to write.
1593
     */
1594
    static void write(BitStreamWriter& out, const ElementType& element)
1595
96
    {
1596
96
        out.writeBitBuffer(element);
1597
96
    }
1598
1599
    /** Determines whether the bit size of the single element is constant. */
1600
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
1601
};
1602
1603
using BitBufferArrayTraits = BasicBitBufferArrayTraits<>;
1604
1605
/**
1606
 * Array traits for Zserio enumeration type.
1607
 */
1608
template <typename T>
1609
struct EnumArrayTraits
1610
{
1611
    /** Element type. */
1612
    using ElementType = T;
1613
1614
    /**
1615
     * Calculates bit size of the array element.
1616
     *
1617
     * \param element Element to use for calculation.
1618
     *
1619
     * \return Bit size of the array element.
1620
     */
1621
    static size_t bitSizeOf(size_t, ElementType element)
1622
97
    {
1623
97
        return zserio::bitSizeOf(element);
1624
97
    }
1625
1626
    /**
1627
     * Initializes indexed offsets of the single array element.
1628
     *
1629
     * \param bitPosition Current bit position.
1630
     * \param element Element to use for calculation.
1631
     *
1632
     * \return Updated bit position which points to the first bit after the array element.
1633
     */
1634
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
1635
97
    {
1636
97
        return zserio::initializeOffsets(bitPosition, element);
1637
97
    }
1638
1639
    /**
1640
     * Reads the single array element.
1641
     *
1642
     * \param in Bit stream reader.
1643
     *
1644
     * \return Read element.
1645
     */
1646
    static ElementType read(BitStreamReader& in, size_t = 0)
1647
97
    {
1648
97
        return zserio::read<ElementType>(in);
1649
97
    }
1650
1651
    /**
1652
     * Writes the single array element.
1653
     *
1654
     * \param out Bit stream writer to use.
1655
     * \param element Element to write.
1656
     */
1657
    static void write(BitStreamWriter& out, ElementType element)
1658
97
    {
1659
97
        zserio::write(out, element);
1660
97
    }
1661
1662
    // Be aware that T can be varuint, so bitSizeOf cannot return constant value.
1663
    /** Determines whether the bit size of the single element is constant. */
1664
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
1665
};
1666
1667
/**
1668
 * Array traits for Zserio bitmask type.
1669
 */
1670
template <typename T>
1671
struct BitmaskArrayTraits
1672
{
1673
    /** Element type. */
1674
    using ElementType = T;
1675
1676
    /**
1677
     * Calculates bit size of the array element.
1678
     *
1679
     * \param element Element to use for calculation.
1680
     *
1681
     * \return Bit size of the array element.
1682
     */
1683
    static size_t bitSizeOf(size_t, ElementType element)
1684
96
    {
1685
96
        return element.bitSizeOf();
1686
96
    }
1687
1688
    /**
1689
     * Initializes indexed offsets of the single array element.
1690
     *
1691
     * \param bitPosition Current bit position.
1692
     * \param element Element to use for calculation.
1693
     *
1694
     * \return Updated bit position which points to the first bit after the array element.
1695
     */
1696
    static size_t initializeOffsets(size_t bitPosition, ElementType element)
1697
96
    {
1698
96
        return element.initializeOffsets(bitPosition);
1699
96
    }
1700
1701
    /**
1702
     * Reads the single array element.
1703
     *
1704
     * \param in Bit stream reader.
1705
     *
1706
     * \return Read element.
1707
     */
1708
    static ElementType read(BitStreamReader& in, size_t = 0)
1709
96
    {
1710
96
        return ElementType(in);
1711
96
    }
1712
1713
    /**
1714
     * Writes the single array element.
1715
     *
1716
     * \param out Bit stream writer to use.
1717
     * \param element Element to write.
1718
     */
1719
    static void write(BitStreamWriter& out, ElementType element)
1720
96
    {
1721
96
        element.write(out);
1722
96
    }
1723
1724
    // Be aware that T can be varuint, so bitSizeOf cannot return constant value.
1725
    /** Determines whether the bit size of the single element is constant. */
1726
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
1727
};
1728
1729
/**
1730
 * Array traits for Zserio structure, choice and union types.
1731
 */
1732
template <typename T, typename ELEMENT_FACTORY>
1733
class ObjectArrayTraits
1734
{
1735
public:
1736
    /** Element type. */
1737
    using ElementType = T;
1738
1739
    /** Allocator type. */
1740
    using allocator_type = typename ElementType::allocator_type;
1741
1742
    /** Typedef for the array's owner type. */
1743
    using OwnerType = typename ELEMENT_FACTORY::OwnerType;
1744
1745
    /**
1746
     * Calculates bit size of the array element.
1747
     *
1748
     * \param bitPosition Current bit position.
1749
     * \param element Element to use for calculation.
1750
     *
1751
     * \return Bit size of the array element.
1752
     */
1753
    static size_t bitSizeOf(const OwnerType&, size_t bitPosition, const ElementType& element)
1754
192
    {
1755
192
        return element.bitSizeOf(bitPosition);
1756
192
    }
1757
1758
    /**
1759
     * Initializes indexed offsets of the single array element.
1760
     *
1761
     * \param bitPosition Current bit position.
1762
     * \param element Element to use.
1763
     *
1764
     * \return Updated bit position which points to the first bit after the array element.
1765
     */
1766
    static size_t initializeOffsets(OwnerType&, size_t bitPosition, ElementType& element)
1767
192
    {
1768
192
        return element.initializeOffsets(bitPosition);
1769
192
    }
1770
1771
    /**
1772
     * Reads the single array element.
1773
     *
1774
     * \param owner Owner of the array.
1775
     * \param rawArray Raw array to use.
1776
     * \param in Bit stream reader.
1777
     * \param index Index need in case of parameterized type which depends on the current index.
1778
     */
1779
    template <typename RAW_ARRAY>
1780
    static void read(OwnerType& owner, RAW_ARRAY& rawArray,
1781
            BitStreamReader& in, size_t index)
1782
192
    {
1783
192
        ELEMENT_FACTORY::create(owner, rawArray, in, index);
1784
192
    }
1785
1786
    /**
1787
     * Writes the single array element.
1788
     *
1789
     * \param out Bit stream writer to use.
1790
     * \param element Element to write.
1791
     */
1792
    static void write(const OwnerType&, BitStreamWriter& out, const ElementType& element)
1793
192
    {
1794
192
        element.write(out);
1795
192
    }
1796
1797
    /** Determines whether the bit size of the single element is constant. */
1798
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
1799
};
1800
1801
namespace detail
1802
{
1803
1804
template <typename ARRAY_TRAITS>
1805
struct packed_array_traits_overloaded : std::false_type
1806
{};
1807
1808
template <typename T, typename ELEMENT_FACTORY>
1809
struct packed_array_traits_overloaded<ObjectArrayTraits<T, ELEMENT_FACTORY>> : std::true_type
1810
{};
1811
1812
} // namespace detail
1813
1814
/**
1815
 * Packed array traits.
1816
 *
1817
 * Packed array traits are used for all packable built-in types. Works with a single DeltaContext.
1818
 */
1819
template <typename ARRAY_TRAITS, typename = void>
1820
class PackedArrayTraits
1821
{
1822
public:
1823
    /** Typedef for array traits. */
1824
    using ArrayTraits = ARRAY_TRAITS;
1825
1826
    /** Element type. */
1827
    using ElementType = typename ARRAY_TRAITS::ElementType;
1828
1829
    /**
1830
     * Calls context initialization step for the current element.
1831
     *
1832
     * Available for traits which do not need the owner.
1833
     *
1834
     * \param deltaContext Delta context.
1835
     * \param element Current element.
1836
     */
1837
    static void initContext(DeltaContext& deltaContext, ElementType element)
1838
9.69k
    {
1839
9.69k
        deltaContext.template init<ArrayTraits>(element);
1840
9.69k
    }
1841
1842
    /**
1843
     * Returns length of the array element stored in the bit stream in bits.
1844
     *
1845
     * Available for traits which do not need the owner.
1846
     *
1847
     * \param deltaContext Delta context.
1848
     * \param element Current element.
1849
     *
1850
     * \return Length of the array element stored in the bit stream in bits.
1851
     */
1852
    static size_t bitSizeOf(DeltaContext& deltaContext, size_t, ElementType element)
1853
6.46k
    {
1854
6.46k
        return deltaContext.template bitSizeOf<ArrayTraits>(element);
1855
6.46k
    }
1856
1857
    /**
1858
     * Calls indexed offsets initialization for the current element.
1859
     *
1860
     * Available for traits which do not need the owner.
1861
     *
1862
     * \param deltaContext Delta context.
1863
     * \param bitPosition Current bit stream position.
1864
     * \param element Current element.
1865
     *
1866
     * \return Updated bit stream position which points to the first bit after this element.
1867
     */
1868
    static size_t initializeOffsets(DeltaContext& deltaContext, size_t bitPosition, ElementType element)
1869
3.23k
    {
1870
3.23k
        return bitPosition + bitSizeOf(deltaContext, bitPosition, element);
1871
3.23k
    }
1872
1873
    /**
1874
     * Reads an element from the bit stream.
1875
     *
1876
     * Available for traits which do not need the owner.
1877
     *
1878
     * \param deltaContext Delta context.
1879
     * \param in Bit stream reader.
1880
     *
1881
     * \return Read element value.
1882
     */
1883
    static ElementType read(DeltaContext& deltaContext, BitStreamReader& in, size_t = 0)
1884
3.23k
    {
1885
3.23k
        return deltaContext.template read<ArrayTraits>(in);
1886
3.23k
    }
1887
1888
    /**
1889
     * Writes the element to the bit stream.
1890
     *
1891
     * Available for traits which do not need the owner.
1892
     *
1893
     * \param deltaContext Delta context.
1894
     * \param out Bit stream writer.
1895
     * \param element Element to write.
1896
     */
1897
    static void write(DeltaContext& deltaContext, BitStreamWriter& out, ElementType element)
1898
3.23k
    {
1899
3.23k
        deltaContext.template write<ArrayTraits>(out, element);
1900
3.23k
    }
1901
};
1902
1903
/**
1904
 * Specialization of packed array traits for traits which needs the array's owner.
1905
 *
1906
 * This packed array traits are used for all packable built-in types which needs the array's owner.
1907
 */
1908
template <typename ARRAY_TRAITS>
1909
class PackedArrayTraits<ARRAY_TRAITS, typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value>::type>
1910
{
1911
public:
1912
    /** Typedef for array traits. */
1913
    using ArrayTraits = ARRAY_TRAITS;
1914
1915
    /** Element type. */
1916
    using ElementType = typename ARRAY_TRAITS::ElementType;
1917
1918
    /** Typedef for the array's owner type. */
1919
    using OwnerType = typename ARRAY_TRAITS::OwnerType;
1920
1921
    /**
1922
     * Calls context initialization step for the current element.
1923
     *
1924
     * Available for traits which need the owner.
1925
     *
1926
     * \param owner Owner of the current array.
1927
     * \param deltaContext Delta context node which keeps the context.
1928
     * \param element Current element.
1929
     */
1930
    static void initContext(const OwnerType& owner, DeltaContext& deltaContext, ElementType element)
1931
576
    {
1932
576
        deltaContext.template init<ArrayTraits>(owner, element);
1933
576
    }
1934
1935
    /**
1936
     * Returns length of the array element stored in the bit stream in bits.
1937
     *
1938
     * Available for traits which need the owner.
1939
     *
1940
     * \param owner Owner of the current array.
1941
     * \param deltaContext Delta context.
1942
     * \param element Current element.
1943
     *
1944
     * \return Length of the array element stored in the bit stream in bits.
1945
     */
1946
    static size_t bitSizeOf(const OwnerType& owner,
1947
            DeltaContext& deltaContext, size_t, ElementType element)
1948
384
    {
1949
384
        return deltaContext.template bitSizeOf<ArrayTraits>(owner, element);
1950
384
    }
1951
1952
    /**
1953
     * Calls indexed offsets initialization for the current element.
1954
     *
1955
     * Available for traits which need the owner.
1956
     *
1957
     * \param owner Owner of the current array.
1958
     * \param deltaContext Delta context.
1959
     * \param bitPosition Current bit stream position.
1960
     * \param element Current element.
1961
     *
1962
     * \return Updated bit stream position which points to the first bit after this element.
1963
     */
1964
    static size_t initializeOffsets(const OwnerType& owner,
1965
            DeltaContext& deltaContext, size_t bitPosition, ElementType element)
1966
192
    {
1967
192
        return bitPosition + bitSizeOf(owner, deltaContext, bitPosition, element);
1968
192
    }
1969
1970
    /**
1971
     * Reads an element from the bit stream.
1972
     *
1973
     * Available for traits which need the owner.
1974
     *
1975
     * \param owner Owner of the current array.
1976
     * \param deltaContext Delta context.
1977
     * \param in Bit stream reader.
1978
     *
1979
     * \return Read element value.
1980
     */
1981
    static ElementType read(const OwnerType& owner, DeltaContext& deltaContext, BitStreamReader& in, size_t = 0)
1982
192
    {
1983
192
        return deltaContext.template read<ArrayTraits>(owner, in);
1984
192
    }
1985
1986
    /**
1987
     * Writes the element to the bit stream.
1988
     *
1989
     * Available for traits which need the owner.
1990
     *
1991
     * \param owner Owner of the current array.
1992
     * \param deltaContext Delta context.
1993
     * \param out Bit stream writer.
1994
     * \param element Element to write.
1995
     */
1996
    static void write(const OwnerType& owner,
1997
            DeltaContext& deltaContext, BitStreamWriter& out, ElementType element)
1998
192
    {
1999
192
        deltaContext.template write<ArrayTraits>(owner, out, element);
2000
192
    }
2001
};
2002
2003
/**
2004
 * Specialization of packed array traits for Zserio enums.
2005
 */
2006
template <typename T>
2007
class PackedArrayTraits<EnumArrayTraits<T>>
2008
{
2009
public:
2010
    /** Typedef for array traits. */
2011
    using ArrayTraits = EnumArrayTraits<T>;
2012
2013
    /** Element type. */
2014
    using ElementType = T;
2015
2016
    /**
2017
     * Calls context initialization step for the current element.
2018
     *
2019
     * \param deltaContext Delta context.
2020
     * \param element Current element.
2021
     */
2022
    static void initContext(DeltaContext& deltaContext, ElementType element)
2023
288
    {
2024
288
        zserio::initPackingContext(deltaContext, element);
2025
288
    }
2026
2027
    /**
2028
     * Returns length of the array element stored in the bit stream in bits.
2029
     *
2030
     * \param deltaContext Delta context.
2031
     * \param element Current element.
2032
     *
2033
     * \return Length of the array element stored in the bit stream in bits.
2034
     */
2035
    static size_t bitSizeOf(DeltaContext& deltaContext, size_t, ElementType element)
2036
96
    {
2037
96
        return zserio::bitSizeOf(deltaContext, element);
2038
96
    }
2039
2040
    /**
2041
     * Calls indexed offsets initialization for the current element.
2042
     *
2043
     * \param deltaContext Delta context.
2044
     * \param bitPosition Current bit stream position.
2045
     * \param element Current element.
2046
     *
2047
     * \return Updated bit stream position which points to the first bit after this element.
2048
     */
2049
    static size_t initializeOffsets(DeltaContext& deltaContext,
2050
            size_t bitPosition, ElementType element)
2051
96
    {
2052
96
        return zserio::initializeOffsets(deltaContext, bitPosition, element);
2053
96
    }
2054
2055
    /**
2056
     * Reads an element from the bit stream.
2057
     *
2058
     * \param deltaContext Delta context.
2059
     * \param in Bit stream reader.
2060
     *
2061
     * \return Read element value.
2062
     */
2063
    static ElementType read(DeltaContext& deltaContext, BitStreamReader& in, size_t = 0)
2064
96
    {
2065
96
        return zserio::read<ElementType>(deltaContext, in);
2066
96
    }
2067
2068
    /**
2069
     * Writes the element to the bit stream.
2070
     *
2071
     * \param deltaContext Delta context.
2072
     * \param out Bit stream writer.
2073
     * \param element Element to write.
2074
     */
2075
    static void write(DeltaContext& deltaContext, BitStreamWriter& out, ElementType element)
2076
96
    {
2077
96
        zserio::write(deltaContext, out, element);
2078
96
    }
2079
};
2080
2081
/**
2082
 * Specialization of packed array traits for Zserio bitmasks.
2083
 */
2084
template <typename T>
2085
class PackedArrayTraits<BitmaskArrayTraits<T>>
2086
{
2087
public:
2088
    /** Typedef for array traits. */
2089
    using ArrayTraits = BitmaskArrayTraits<T>;
2090
2091
    /** Element type. */
2092
    using ElementType = T;
2093
2094
    /**
2095
     * Calls context initialization step for the current element.
2096
     *
2097
     * \param deltaContext Delta context.
2098
     */
2099
    static void initContext(DeltaContext& deltaContext, const ElementType& element)
2100
288
    {
2101
288
        element.initPackingContext(deltaContext);
2102
288
    }
2103
2104
    /**
2105
     * Returns length of the array element stored in the bit stream in bits.
2106
     *
2107
     * \param deltaContext Delta context.
2108
     * \param bitPosition Current bit stream position.
2109
     * \param element Current element.
2110
     *
2111
     * \return Length of the array element stored in the bit stream in bits.
2112
     */
2113
    static size_t bitSizeOf(DeltaContext& deltaContext, size_t bitPosition, const ElementType& element)
2114
96
    {
2115
96
        return element.bitSizeOf(deltaContext, bitPosition);
2116
96
    }
2117
2118
    /**
2119
     * Calls indexed offsets initialization for the current element.
2120
     *
2121
     * \param deltaContext Delta context.
2122
     * \param bitPosition Current bit stream position.
2123
     * \param element Current element.
2124
     *
2125
     * \return Updated bit stream position which points to the first bit after this element.
2126
     */
2127
    static size_t initializeOffsets(DeltaContext& deltaContext, size_t bitPosition, const ElementType& element)
2128
96
    {
2129
96
        return element.initializeOffsets(deltaContext, bitPosition);
2130
96
    }
2131
2132
    /**
2133
     * Reads an element from the bit stream.
2134
     *
2135
     * \param deltaContext Delta context.
2136
     * \param in Bit stream reader.
2137
     *
2138
     * \return Read element.
2139
     */
2140
    static ElementType read(DeltaContext& deltaContext, BitStreamReader& in, size_t = 0)
2141
96
    {
2142
96
        return ElementType(deltaContext, in);
2143
96
    }
2144
2145
    /**
2146
     * Writes the element to the bit stream.
2147
     *
2148
     * \param deltaContext Delta context.
2149
     * \param out Bit stream writer.
2150
     * \param element Element to write.
2151
     */
2152
    static void write(DeltaContext& deltaContext, BitStreamWriter& out, const ElementType& element)
2153
96
    {
2154
96
        element.write(deltaContext, out);
2155
96
    }
2156
};
2157
2158
// note: enable_if is needed to be more specific then specialization for types which needs owner type
2159
/**
2160
 * Specialization of packed array traits for Zserio objects.
2161
 */
2162
template <typename T, typename ELEMENT_FACTORY>
2163
class PackedArrayTraits<ObjectArrayTraits<T, ELEMENT_FACTORY>,
2164
        typename std::enable_if<has_owner_type<ObjectArrayTraits<T, ELEMENT_FACTORY>>::value>::type>
2165
{
2166
public:
2167
    /** Typedef for array traits. */
2168
    using ArrayTraits = ObjectArrayTraits<T, ELEMENT_FACTORY>;
2169
2170
    /** Element type. */
2171
    using ElementType = T;
2172
2173
    /** Allocator type. */
2174
    using allocator_type = typename T::allocator_type;
2175
2176
    /** Typedef for the array's owner type. */
2177
    using OwnerType = typename ArrayTraits::OwnerType;
2178
2179
    /**
2180
     * Calls context initialization step for the current element.
2181
     *
2182
     * \param packingContext Packing context node which keeps the appropriate subtree of contexts.
2183
     */
2184
    template <typename PACKING_CONTEXT>
2185
    static void initContext(const typename ArrayTraits::OwnerType&,
2186
            PACKING_CONTEXT& packingContext, const ElementType& element)
2187
576
    {
2188
576
        element.initPackingContext(packingContext);
2189
576
    }
2190
2191
    /**
2192
     * Returns length of the array element stored in the bit stream in bits.
2193
     *
2194
     * \param packingContext Packing context node which keeps the appropriate subtree of contexts.
2195
     * \param bitPosition Current bit stream position.
2196
     * \param element Current element.
2197
     *
2198
     * \return Length of the array element stored in the bit stream in bits.
2199
     */
2200
    template <typename PACKING_CONTEXT>
2201
    static size_t bitSizeOf(const typename ArrayTraits::OwnerType&,
2202
            PACKING_CONTEXT& packingContext, size_t bitPosition, const ElementType& element)
2203
192
    {
2204
192
        return element.bitSizeOf(packingContext, bitPosition);
2205
192
    }
2206
2207
    /**
2208
     * Calls indexed offsets initialization for the current element.
2209
     *
2210
     * \param packingContext Packing context node which keeps the appropriate subtree of contexts.
2211
     * \param bitPosition Current bit stream position.
2212
     * \param element Current element.
2213
     *
2214
     * \return Updated bit stream position which points to the first bit after this element.
2215
     */
2216
    template <typename PACKING_CONTEXT>
2217
    static size_t initializeOffsets(const typename ArrayTraits::OwnerType&,
2218
            PACKING_CONTEXT& packingContext, size_t bitPosition, ElementType& element)
2219
192
    {
2220
192
        return element.initializeOffsets(packingContext, bitPosition);
2221
192
    }
2222
2223
    /**
2224
     * Reads an element from the bit stream.
2225
     *
2226
     * \param owner Owner of the array.
2227
     * \param rawArray Raw array to use.
2228
     * \param packingContext Packing context node which keeps the appropriate subtree of contexts.
2229
     * \param in Bit stream reader.
2230
     * \param allocator Allocator to use.
2231
     * \param index Index of the current element.
2232
     */
2233
    template <typename RAW_ARRAY, typename PACKING_CONTEXT>
2234
    static void read(typename ArrayTraits::OwnerType& owner, RAW_ARRAY& rawArray,
2235
            PACKING_CONTEXT& packingContext, BitStreamReader& in, size_t index)
2236
192
    {
2237
192
        ELEMENT_FACTORY::create(owner, rawArray, packingContext, in, index);
2238
192
    }
2239
2240
    /**
2241
     * Writes the element to the bit stream.
2242
     *
2243
     * \param packingContext Packing context node which keeps the appropriate subtree of contexts.
2244
     * \param out Bit stream writer.
2245
     * \param element Element to write.
2246
     */
2247
    template <typename PACKING_CONTEXT>
2248
    static void write(const typename ArrayTraits::OwnerType&,
2249
            PACKING_CONTEXT& packingContext, BitStreamWriter& out, const ElementType& element)
2250
192
    {
2251
192
        element.write(packingContext, out);
2252
192
    }
2253
};
2254
2255
} // namespace zserio
2256
2257
#endif // ZSERIO_ARRAY_TRAITS_H_INC