Coverage Report

Created: 2024-04-30 09:35

src/zserio/ArrayTraits.h
Line
Count
Source
1
#ifndef ZSERIO_ARRAY_TRAITS_H_INC
2
#define ZSERIO_ARRAY_TRAITS_H_INC
3
4
#include <string>
5
#include <type_traits>
6
#include <vector>
7
8
#include "zserio/BitPositionUtil.h"
9
#include "zserio/BitSizeOfCalculator.h"
10
#include "zserio/BitStreamReader.h"
11
#include "zserio/BitStreamWriter.h"
12
#include "zserio/DeltaContext.h"
13
#include "zserio/Enums.h"
14
#include "zserio/SizeConvertUtil.h"
15
#include "zserio/Traits.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, BitStreamReader& in, size_t index)
1781
192
    {
1782
192
        ELEMENT_FACTORY::create(owner, rawArray, in, index);
1783
192
    }
1784
1785
    /**
1786
     * Writes the single array element.
1787
     *
1788
     * \param out Bit stream writer to use.
1789
     * \param element Element to write.
1790
     */
1791
    static void write(const OwnerType&, BitStreamWriter& out, const ElementType& element)
1792
192
    {
1793
192
        element.write(out);
1794
192
    }
1795
1796
    /** Determines whether the bit size of the single element is constant. */
1797
    static constexpr bool IS_BITSIZEOF_CONSTANT = false;
1798
};
1799
1800
namespace detail
1801
{
1802
1803
template <typename ARRAY_TRAITS>
1804
struct packed_array_traits_overloaded : std::false_type
1805
{};
1806
1807
template <typename T, typename ELEMENT_FACTORY>
1808
struct packed_array_traits_overloaded<ObjectArrayTraits<T, ELEMENT_FACTORY>> : std::true_type
1809
{};
1810
1811
} // namespace detail
1812
1813
/**
1814
 * Packed array traits.
1815
 *
1816
 * Packed array traits are used for all packable built-in types. Works with a single DeltaContext.
1817
 */
1818
template <typename ARRAY_TRAITS, typename = void>
1819
class PackedArrayTraits
1820
{
1821
public:
1822
    /** Typedef for array traits. */
1823
    using ArrayTraits = ARRAY_TRAITS;
1824
1825
    /** Element type. */
1826
    using ElementType = typename ARRAY_TRAITS::ElementType;
1827
1828
    /**
1829
     * Calls context initialization step for the current element.
1830
     *
1831
     * Available for traits which do not need the owner.
1832
     *
1833
     * \param deltaContext Delta context.
1834
     * \param element Current element.
1835
     */
1836
    static void initContext(DeltaContext& deltaContext, ElementType element)
1837
9.69k
    {
1838
9.69k
        deltaContext.template init<ArrayTraits>(element);
1839
9.69k
    }
1840
1841
    /**
1842
     * Returns length of the array element stored in the bit stream in bits.
1843
     *
1844
     * Available for traits which do not need the owner.
1845
     *
1846
     * \param deltaContext Delta context.
1847
     * \param element Current element.
1848
     *
1849
     * \return Length of the array element stored in the bit stream in bits.
1850
     */
1851
    static size_t bitSizeOf(DeltaContext& deltaContext, size_t, ElementType element)
1852
6.46k
    {
1853
6.46k
        return deltaContext.template bitSizeOf<ArrayTraits>(element);
1854
6.46k
    }
1855
1856
    /**
1857
     * Calls indexed offsets initialization for the current element.
1858
     *
1859
     * Available for traits which do not need the owner.
1860
     *
1861
     * \param deltaContext Delta context.
1862
     * \param bitPosition Current bit stream position.
1863
     * \param element Current element.
1864
     *
1865
     * \return Updated bit stream position which points to the first bit after this element.
1866
     */
1867
    static size_t initializeOffsets(DeltaContext& deltaContext, size_t bitPosition, ElementType element)
1868
3.23k
    {
1869
3.23k
        return bitPosition + bitSizeOf(deltaContext, bitPosition, element);
1870
3.23k
    }
1871
1872
    /**
1873
     * Reads an element from the bit stream.
1874
     *
1875
     * Available for traits which do not need the owner.
1876
     *
1877
     * \param deltaContext Delta context.
1878
     * \param in Bit stream reader.
1879
     *
1880
     * \return Read element value.
1881
     */
1882
    static ElementType read(DeltaContext& deltaContext, BitStreamReader& in, size_t = 0)
1883
3.23k
    {
1884
3.23k
        return deltaContext.template read<ArrayTraits>(in);
1885
3.23k
    }
1886
1887
    /**
1888
     * Writes the element to the bit stream.
1889
     *
1890
     * Available for traits which do not need the owner.
1891
     *
1892
     * \param deltaContext Delta context.
1893
     * \param out Bit stream writer.
1894
     * \param element Element to write.
1895
     */
1896
    static void write(DeltaContext& deltaContext, BitStreamWriter& out, ElementType element)
1897
3.23k
    {
1898
3.23k
        deltaContext.template write<ArrayTraits>(out, element);
1899
3.23k
    }
1900
};
1901
1902
/**
1903
 * Specialization of packed array traits for traits which needs the array's owner.
1904
 *
1905
 * This packed array traits are used for all packable built-in types which needs the array's owner.
1906
 */
1907
template <typename ARRAY_TRAITS>
1908
class PackedArrayTraits<ARRAY_TRAITS, typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value>::type>
1909
{
1910
public:
1911
    /** Typedef for array traits. */
1912
    using ArrayTraits = ARRAY_TRAITS;
1913
1914
    /** Element type. */
1915
    using ElementType = typename ARRAY_TRAITS::ElementType;
1916
1917
    /** Typedef for the array's owner type. */
1918
    using OwnerType = typename ARRAY_TRAITS::OwnerType;
1919
1920
    /**
1921
     * Calls context initialization step for the current element.
1922
     *
1923
     * Available for traits which need the owner.
1924
     *
1925
     * \param owner Owner of the current array.
1926
     * \param deltaContext Delta context node which keeps the context.
1927
     * \param element Current element.
1928
     */
1929
    static void initContext(const OwnerType& owner, DeltaContext& deltaContext, ElementType element)
1930
576
    {
1931
576
        deltaContext.template init<ArrayTraits>(owner, element);
1932
576
    }
1933
1934
    /**
1935
     * Returns length of the array element stored in the bit stream in bits.
1936
     *
1937
     * Available for traits which need the owner.
1938
     *
1939
     * \param owner Owner of the current array.
1940
     * \param deltaContext Delta context.
1941
     * \param element Current element.
1942
     *
1943
     * \return Length of the array element stored in the bit stream in bits.
1944
     */
1945
    static size_t bitSizeOf(const OwnerType& owner, DeltaContext& deltaContext, size_t, ElementType element)
1946
384
    {
1947
384
        return deltaContext.template bitSizeOf<ArrayTraits>(owner, element);
1948
384
    }
1949
1950
    /**
1951
     * Calls indexed offsets initialization for the current element.
1952
     *
1953
     * Available for traits which need the owner.
1954
     *
1955
     * \param owner Owner of the current array.
1956
     * \param deltaContext Delta context.
1957
     * \param bitPosition Current bit stream position.
1958
     * \param element Current element.
1959
     *
1960
     * \return Updated bit stream position which points to the first bit after this element.
1961
     */
1962
    static size_t initializeOffsets(
1963
            const OwnerType& owner, DeltaContext& deltaContext, size_t bitPosition, ElementType element)
1964
192
    {
1965
192
        return bitPosition + bitSizeOf(owner, deltaContext, bitPosition, element);
1966
192
    }
1967
1968
    /**
1969
     * Reads an element from the bit stream.
1970
     *
1971
     * Available for traits which need the owner.
1972
     *
1973
     * \param owner Owner of the current array.
1974
     * \param deltaContext Delta context.
1975
     * \param in Bit stream reader.
1976
     *
1977
     * \return Read element value.
1978
     */
1979
    static ElementType read(const OwnerType& owner, DeltaContext& deltaContext, BitStreamReader& in, size_t = 0)
1980
192
    {
1981
192
        return deltaContext.template read<ArrayTraits>(owner, in);
1982
192
    }
1983
1984
    /**
1985
     * Writes the element to the bit stream.
1986
     *
1987
     * Available for traits which need the owner.
1988
     *
1989
     * \param owner Owner of the current array.
1990
     * \param deltaContext Delta context.
1991
     * \param out Bit stream writer.
1992
     * \param element Element to write.
1993
     */
1994
    static void write(
1995
            const OwnerType& owner, DeltaContext& deltaContext, BitStreamWriter& out, ElementType element)
1996
192
    {
1997
192
        deltaContext.template write<ArrayTraits>(owner, out, element);
1998
192
    }
1999
};
2000
2001
/**
2002
 * Specialization of packed array traits for Zserio enums.
2003
 */
2004
template <typename T>
2005
class PackedArrayTraits<EnumArrayTraits<T>>
2006
{
2007
public:
2008
    /** Typedef for array traits. */
2009
    using ArrayTraits = EnumArrayTraits<T>;
2010
2011
    /** Element type. */
2012
    using ElementType = T;
2013
2014
    /**
2015
     * Calls context initialization step for the current element.
2016
     *
2017
     * \param deltaContext Delta context.
2018
     * \param element Current element.
2019
     */
2020
    static void initContext(DeltaContext& deltaContext, ElementType element)
2021
288
    {
2022
288
        zserio::initPackingContext(deltaContext, element);
2023
288
    }
2024
2025
    /**
2026
     * Returns length of the array element stored in the bit stream in bits.
2027
     *
2028
     * \param deltaContext Delta context.
2029
     * \param element Current element.
2030
     *
2031
     * \return Length of the array element stored in the bit stream in bits.
2032
     */
2033
    static size_t bitSizeOf(DeltaContext& deltaContext, size_t, ElementType element)
2034
96
    {
2035
96
        return zserio::bitSizeOf(deltaContext, element);
2036
96
    }
2037
2038
    /**
2039
     * Calls indexed offsets initialization for the current element.
2040
     *
2041
     * \param deltaContext Delta context.
2042
     * \param bitPosition Current bit stream position.
2043
     * \param element Current element.
2044
     *
2045
     * \return Updated bit stream position which points to the first bit after this element.
2046
     */
2047
    static size_t initializeOffsets(DeltaContext& deltaContext, size_t bitPosition, ElementType element)
2048
96
    {
2049
96
        return zserio::initializeOffsets(deltaContext, bitPosition, element);
2050
96
    }
2051
2052
    /**
2053
     * Reads an element from the bit stream.
2054
     *
2055
     * \param deltaContext Delta context.
2056
     * \param in Bit stream reader.
2057
     *
2058
     * \return Read element value.
2059
     */
2060
    static ElementType read(DeltaContext& deltaContext, BitStreamReader& in, size_t = 0)
2061
96
    {
2062
96
        return zserio::read<ElementType>(deltaContext, in);
2063
96
    }
2064
2065
    /**
2066
     * Writes the element to the bit stream.
2067
     *
2068
     * \param deltaContext Delta context.
2069
     * \param out Bit stream writer.
2070
     * \param element Element to write.
2071
     */
2072
    static void write(DeltaContext& deltaContext, BitStreamWriter& out, ElementType element)
2073
96
    {
2074
96
        zserio::write(deltaContext, out, element);
2075
96
    }
2076
};
2077
2078
/**
2079
 * Specialization of packed array traits for Zserio bitmasks.
2080
 */
2081
template <typename T>
2082
class PackedArrayTraits<BitmaskArrayTraits<T>>
2083
{
2084
public:
2085
    /** Typedef for array traits. */
2086
    using ArrayTraits = BitmaskArrayTraits<T>;
2087
2088
    /** Element type. */
2089
    using ElementType = T;
2090
2091
    /**
2092
     * Calls context initialization step for the current element.
2093
     *
2094
     * \param deltaContext Delta context.
2095
     */
2096
    static void initContext(DeltaContext& deltaContext, const ElementType& element)
2097
288
    {
2098
288
        element.initPackingContext(deltaContext);
2099
288
    }
2100
2101
    /**
2102
     * Returns length of the array element stored in the bit stream in bits.
2103
     *
2104
     * \param deltaContext Delta context.
2105
     * \param bitPosition Current bit stream position.
2106
     * \param element Current element.
2107
     *
2108
     * \return Length of the array element stored in the bit stream in bits.
2109
     */
2110
    static size_t bitSizeOf(DeltaContext& deltaContext, size_t bitPosition, const ElementType& element)
2111
96
    {
2112
96
        return element.bitSizeOf(deltaContext, bitPosition);
2113
96
    }
2114
2115
    /**
2116
     * Calls indexed offsets initialization for the current element.
2117
     *
2118
     * \param deltaContext Delta context.
2119
     * \param bitPosition Current bit stream position.
2120
     * \param element Current element.
2121
     *
2122
     * \return Updated bit stream position which points to the first bit after this element.
2123
     */
2124
    static size_t initializeOffsets(DeltaContext& deltaContext, size_t bitPosition, const ElementType& element)
2125
96
    {
2126
96
        return element.initializeOffsets(deltaContext, bitPosition);
2127
96
    }
2128
2129
    /**
2130
     * Reads an element from the bit stream.
2131
     *
2132
     * \param deltaContext Delta context.
2133
     * \param in Bit stream reader.
2134
     *
2135
     * \return Read element.
2136
     */
2137
    static ElementType read(DeltaContext& deltaContext, BitStreamReader& in, size_t = 0)
2138
96
    {
2139
96
        return ElementType(deltaContext, in);
2140
96
    }
2141
2142
    /**
2143
     * Writes the element to the bit stream.
2144
     *
2145
     * \param deltaContext Delta context.
2146
     * \param out Bit stream writer.
2147
     * \param element Element to write.
2148
     */
2149
    static void write(DeltaContext& deltaContext, BitStreamWriter& out, const ElementType& element)
2150
96
    {
2151
96
        element.write(deltaContext, out);
2152
96
    }
2153
};
2154
2155
// note: enable_if is needed to be more specific then specialization for types which needs owner type
2156
/**
2157
 * Specialization of packed array traits for Zserio objects.
2158
 */
2159
template <typename T, typename ELEMENT_FACTORY>
2160
class PackedArrayTraits<ObjectArrayTraits<T, ELEMENT_FACTORY>,
2161
        typename std::enable_if<has_owner_type<ObjectArrayTraits<T, ELEMENT_FACTORY>>::value>::type>
2162
{
2163
public:
2164
    /** Typedef for array traits. */
2165
    using ArrayTraits = ObjectArrayTraits<T, ELEMENT_FACTORY>;
2166
2167
    /** Element type. */
2168
    using ElementType = T;
2169
2170
    /** Allocator type. */
2171
    using allocator_type = typename T::allocator_type;
2172
2173
    /** Typedef for the array's owner type. */
2174
    using OwnerType = typename ArrayTraits::OwnerType;
2175
2176
    /**
2177
     * Calls context initialization step for the current element.
2178
     *
2179
     * \param packingContext Packing context node which keeps the appropriate subtree of contexts.
2180
     */
2181
    template <typename PACKING_CONTEXT>
2182
    static void initContext(
2183
            const typename ArrayTraits::OwnerType&, PACKING_CONTEXT& packingContext, const ElementType& element)
2184
576
    {
2185
576
        element.initPackingContext(packingContext);
2186
576
    }
2187
2188
    /**
2189
     * Returns length of the array element stored in the bit stream in bits.
2190
     *
2191
     * \param packingContext Packing context node which keeps the appropriate subtree of contexts.
2192
     * \param bitPosition Current bit stream position.
2193
     * \param element Current element.
2194
     *
2195
     * \return Length of the array element stored in the bit stream in bits.
2196
     */
2197
    template <typename PACKING_CONTEXT>
2198
    static size_t bitSizeOf(const typename ArrayTraits::OwnerType&, PACKING_CONTEXT& packingContext,
2199
            size_t bitPosition, const ElementType& element)
2200
192
    {
2201
192
        return element.bitSizeOf(packingContext, bitPosition);
2202
192
    }
2203
2204
    /**
2205
     * Calls indexed offsets initialization for the current element.
2206
     *
2207
     * \param packingContext Packing context node which keeps the appropriate subtree of contexts.
2208
     * \param bitPosition Current bit stream position.
2209
     * \param element Current element.
2210
     *
2211
     * \return Updated bit stream position which points to the first bit after this element.
2212
     */
2213
    template <typename PACKING_CONTEXT>
2214
    static size_t initializeOffsets(const typename ArrayTraits::OwnerType&, PACKING_CONTEXT& packingContext,
2215
            size_t bitPosition, ElementType& element)
2216
192
    {
2217
192
        return element.initializeOffsets(packingContext, bitPosition);
2218
192
    }
2219
2220
    /**
2221
     * Reads an element from the bit stream.
2222
     *
2223
     * \param owner Owner of the array.
2224
     * \param rawArray Raw array to use.
2225
     * \param packingContext Packing context node which keeps the appropriate subtree of contexts.
2226
     * \param in Bit stream reader.
2227
     * \param allocator Allocator to use.
2228
     * \param index Index of the current element.
2229
     */
2230
    template <typename RAW_ARRAY, typename PACKING_CONTEXT>
2231
    static void read(typename ArrayTraits::OwnerType& owner, RAW_ARRAY& rawArray,
2232
            PACKING_CONTEXT& packingContext, BitStreamReader& in, size_t index)
2233
192
    {
2234
192
        ELEMENT_FACTORY::create(owner, rawArray, packingContext, in, index);
2235
192
    }
2236
2237
    /**
2238
     * Writes the element to the bit stream.
2239
     *
2240
     * \param packingContext Packing context node which keeps the appropriate subtree of contexts.
2241
     * \param out Bit stream writer.
2242
     * \param element Element to write.
2243
     */
2244
    template <typename PACKING_CONTEXT>
2245
    static void write(const typename ArrayTraits::OwnerType&, PACKING_CONTEXT& packingContext,
2246
            BitStreamWriter& out, const ElementType& element)
2247
192
    {
2248
192
        element.write(packingContext, out);
2249
192
    }
2250
};
2251
2252
} // namespace zserio
2253
2254
#endif // ZSERIO_ARRAY_TRAITS_H_INC