BitStream
Loading...
Searching...
No Matches
array_traits.h
Go to the documentation of this file.
1#pragma once
2#include "../utility/assert.h"
3#include "../utility/meta.h"
4#include "../utility/parameter.h"
5
6#include "../stream/serialize_traits.h"
7
8#include "../traits/bool_trait.h"
9#include "../traits/integral_traits.h"
10
11#include <cstdint>
12
13namespace bitstream
14{
19 template<typename T, typename = T>
21
27 template<typename T, typename Trait>
29 {
30 private:
31 template<uint32_t Min, uint32_t Max, typename Stream>
32 static bool serialize_difference(Stream& stream, int& previous, int& current, uint32_t& difference)
33 {
34 bool use_bits;
35 if constexpr (Stream::writing)
36 use_bits = difference <= Max;
37 BS_ASSERT(stream.template serialize<bool>(use_bits));
38 if (use_bits)
39 {
40 using bounded_trait = bounded_int<uint32_t, Min, Max>;
41
42 BS_ASSERT(stream.template serialize<bounded_trait>(difference));
43 if constexpr (Stream::reading)
44 current = previous + difference;
45 previous = current;
46 return true;
47 }
48
49 return false;
50 }
51
52 template<typename Stream>
53 static bool serialize_index(Stream& stream, int& previous, int& current, int max_size)
54 {
55 uint32_t difference;
56 if constexpr (Stream::writing)
57 {
58 BS_ASSERT(previous < current);
59 difference = current - previous;
60 BS_ASSERT(difference > 0);
61 }
62
63 // +1 (1 bit)
64 bool plus_one;
65 if constexpr (Stream::writing)
66 plus_one = difference == 1;
67 BS_ASSERT(stream.template serialize<bool>(plus_one));
68 if (plus_one)
69 {
70 if constexpr (Stream::reading)
71 current = previous + 1;
72 previous = current;
73 return true;
74 }
75
76 // [+2,5] -> [0,3] (2 bits)
77 if (serialize_difference<2, 5>(stream, previous, current, difference))
78 return true;
79
80 // [6,13] -> [0,7] (3 bits)
81 if (serialize_difference<6, 13>(stream, previous, current, difference))
82 return true;
83
84 // [14,29] -> [0,15] (4 bits)
85 if (serialize_difference<14, 29>(stream, previous, current, difference))
86 return true;
87
88 // [30,61] -> [0,31] (5 bits)
89 if (serialize_difference<30, 61>(stream, previous, current, difference))
90 return true;
91
92 // [62,125] -> [0,63] (6 bits)
93 if (serialize_difference<62, 125>(stream, previous, current, difference))
94 return true;
95
96 // [126,MaxObjects+1]
97 BS_ASSERT(stream.template serialize<uint32_t>(difference, 126, max_size));
98 if constexpr (Stream::reading)
99 current = previous + difference;
100 previous = current;
101 return true;
102 }
103
104 public:
116 template<typename Stream, typename Compare, typename... Args>
118 static serialize(Stream& writer, T* values, int max_size, Compare compare, Args&&... args) noexcept
119 {
120 int prev_index = -1;
121 for (int index = 0; index < max_size; index++)
122 {
123 if (!compare(values[index]))
124 continue;
125
126 BS_ASSERT(serialize_index(writer, prev_index, index, max_size));
127
128 BS_ASSERT(writer.template serialize<Trait>(values[index], std::forward<Args>(args)...));
129 }
130
131 BS_ASSERT(serialize_index(writer, prev_index, max_size, max_size));
132
133 return true;
134 }
135
146 template<typename Stream, typename... Args>
148 static serialize(Stream& reader, T* values, int max_size, Args&&... args) noexcept
149 {
150 int prev_index = -1;
151 int index = 0;
152 while (true)
153 {
154 BS_ASSERT(serialize_index(reader, prev_index, index, max_size));
155
156 if (index == max_size)
157 break;
158
159 BS_ASSERT(reader.template serialize<Trait>(values[index], std::forward<Args>(args)...));
160 }
161
162 return true;
163 }
164 };
165}
#define BS_ASSERT(...)
Definition assert.h:15
std::enable_if_t< T::writing, R > is_writing_t
Definition meta.h:25
std::enable_if_t< T::reading, R > is_reading_t
Definition meta.h:28
Definition bounded_range.h:28
Wrapper type for subsets of arrays.
Definition array_traits.h:20
Wrapper type for compiletime known integer bounds.
Definition integral_traits.h:20
static utility::is_writing_t< Stream > serialize(Stream &writer, T *values, int max_size, Compare compare, Args &&... args) noexcept
Writes a subset of the array values into the writer.
Definition array_traits.h:118
static utility::is_reading_t< Stream > serialize(Stream &reader, T *values, int max_size, Args &&... args) noexcept
Writes a subset of a serialized array into values.
Definition array_traits.h:148
A class for specializing trait serialization functions.
Definition serialize_traits.h:11