@@ -19,6 +19,101 @@ namespace bitstream
1919 template <typename T, T = (std::numeric_limits<T>::min)(), T = (std::numeric_limits<T>::max)()>
2020 struct bounded_int ;
2121
22+ #pragma region const integral types
23+ /* *
24+ * @brief A trait used to serialize integer values with compiletime bounds
25+ * @tparam T A type matching an integer value
26+ * @tparam Min The lower bound. Inclusive
27+ * @tparam Max The upper bound. Inclusive
28+ */
29+ template <typename T, T Min, T Max>
30+ struct serialize_traits <bounded_int<T, Min, Max>, typename std::enable_if_t <std::is_integral_v<T> && !std::is_const_v<T>>>
31+ {
32+ static_assert (sizeof (T) <= 8 , " Integers larger than 8 bytes are currently not supported. You will have to write this functionality yourself" );
33+
34+ /* *
35+ * @brief Writes an integer into the @p writer
36+ * @param writer The stream to write to
37+ * @param value The value to serialize
38+ * @return Success
39+ */
40+ template <typename Stream>
41+ typename utility::is_writing_t <Stream>
42+ static serialize (Stream& writer, in<T> value) noexcept
43+ {
44+ static_assert (Min < Max);
45+
46+ BS_ASSERT (value >= Min && value <= Max);
47+
48+ constexpr uint32_t num_bits = utility::bits_in_range (Min, Max);
49+
50+ static_assert (num_bits <= sizeof (T) * 8 );
51+
52+ if constexpr (sizeof (T) > 4 && num_bits > 32 )
53+ {
54+ // If the given range is bigger than a word (32 bits)
55+ uint32_t unsigned_value = static_cast <uint32_t >(value - Min);
56+ BS_ASSERT (writer.serialize_bits (unsigned_value, 32 ));
57+
58+ unsigned_value = static_cast <uint32_t >((value - Min) >> 32 );
59+ BS_ASSERT (writer.serialize_bits (unsigned_value, num_bits - 32 ));
60+ }
61+ else
62+ {
63+ // If the given range is smaller than or equal to a word (32 bits)
64+ uint32_t unsigned_value = static_cast <uint32_t >(value - Min);
65+ BS_ASSERT (writer.serialize_bits (unsigned_value, num_bits));
66+ }
67+
68+ return true ;
69+ }
70+
71+ /* *
72+ * @brief Reads an integer from the @p writer into @p value
73+ * @param reader The stream to read from
74+ * @param value The value to serialize
75+ * @return Success
76+ */
77+ template <typename Stream>
78+ typename utility::is_reading_t <Stream>
79+ static serialize (Stream& reader, T& value) noexcept
80+ {
81+ static_assert (Min < Max);
82+
83+ constexpr uint32_t num_bits = utility::bits_in_range (Min, Max);
84+
85+ static_assert (num_bits <= sizeof (T) * 8 );
86+
87+ if constexpr (sizeof (T) > 4 && num_bits > 32 )
88+ {
89+ // If the given range is bigger than a word (32 bits)
90+ value = 0 ;
91+ uint32_t unsigned_value;
92+
93+ BS_ASSERT (reader.serialize_bits (unsigned_value, 32 ));
94+ value |= static_cast <T>(unsigned_value);
95+
96+ BS_ASSERT (reader.serialize_bits (unsigned_value, num_bits - 32 ));
97+ value |= static_cast <T>(unsigned_value) << 32 ;
98+
99+ value += Min;
100+ }
101+ else
102+ {
103+ // If the given range is smaller than or equal to a word (32 bits)
104+ uint32_t unsigned_value;
105+ BS_ASSERT (reader.serialize_bits (unsigned_value, num_bits));
106+
107+ value = static_cast <T>(unsigned_value) + Min;
108+ }
109+
110+ BS_ASSERT (value >= Min && value <= Max);
111+
112+ return true ;
113+ }
114+ };
115+ #pragma endregion
116+
22117#pragma region integral types
23118 /* *
24119 * @brief A trait used to serialize integer values with runtime bounds
@@ -39,7 +134,7 @@ namespace bitstream
39134 */
40135 template <typename Stream>
41136 typename utility::is_writing_t <Stream>
42- static serialize (Stream& writer, in<T> value, T min = (std::numeric_limits<T>::min)() , T max = (std::numeric_limits<T>::max)() ) noexcept
137+ static serialize (Stream& writer, in<T> value, T min, T max) noexcept
43138 {
44139 BS_ASSERT (min < max);
45140
@@ -81,7 +176,7 @@ namespace bitstream
81176 */
82177 template <typename Stream>
83178 typename utility::is_reading_t <Stream>
84- static serialize (Stream& reader, T& value, T min = (std::numeric_limits<T>::min)() , T max = (std::numeric_limits<T>::max)() ) noexcept
179+ static serialize (Stream& reader, T& value, T min, T max) noexcept
85180 {
86181 BS_ASSERT (min < max);
87182
@@ -121,100 +216,17 @@ namespace bitstream
121216
122217 return true ;
123218 }
124- };
125- #pragma endregion
126-
127- #pragma region const integral types
128- /* *
129- * @brief A trait used to serialize integer values with compiletime bounds
130- * @tparam T A type matching an integer value
131- * @tparam Min The lower bound. Inclusive
132- * @tparam Max The upper bound. Inclusive
133- */
134- template <typename T, T Min, T Max>
135- struct serialize_traits <bounded_int<T, Min, Max>, typename std::enable_if_t <std::is_integral_v<T> && !std::is_const_v<T>>>
136- {
137- static_assert (sizeof (T) <= 8 , " Integers larger than 8 bytes are currently not supported. You will have to write this functionality yourself" );
138219
139220 /* *
140- * @brief Writes an integer into the @p writer
141- * @param writer The stream to write to
221+ * @brief Writes or reads an integer into the @p stream
222+ * @param stream The stream to serialize to/from
142223 * @param value The value to serialize
143224 * @return Success
144225 */
145- template <typename Stream>
146- typename utility::is_writing_t <Stream>
147- static serialize (Stream& writer, in<T> value) noexcept
226+ template <typename Stream, typename U>
227+ static bool serialize (Stream& stream, U&& value) noexcept
148228 {
149- static_assert (Min < Max);
150-
151- BS_ASSERT (value >= Min && value <= Max);
152-
153- constexpr uint32_t num_bits = utility::bits_in_range (Min, Max);
154-
155- static_assert (num_bits <= sizeof (T) * 8 );
156-
157- if constexpr (sizeof (T) > 4 && num_bits > 32 )
158- {
159- // If the given range is bigger than a word (32 bits)
160- uint32_t unsigned_value = static_cast <uint32_t >(value - Min);
161- BS_ASSERT (writer.serialize_bits (unsigned_value, 32 ));
162-
163- unsigned_value = static_cast <uint32_t >((value - Min) >> 32 );
164- BS_ASSERT (writer.serialize_bits (unsigned_value, num_bits - 32 ));
165- }
166- else
167- {
168- // If the given range is smaller than or equal to a word (32 bits)
169- uint32_t unsigned_value = static_cast <uint32_t >(value - Min);
170- BS_ASSERT (writer.serialize_bits (unsigned_value, num_bits));
171- }
172-
173- return true ;
174- }
175-
176- /* *
177- * @brief Reads an integer from the @p writer into @p value
178- * @param reader The stream to read from
179- * @param value The value to serialize
180- * @return Success
181- */
182- template <typename Stream>
183- typename utility::is_reading_t <Stream>
184- static serialize (Stream& reader, T& value) noexcept
185- {
186- static_assert (Min < Max);
187-
188- constexpr uint32_t num_bits = utility::bits_in_range (Min, Max);
189-
190- static_assert (num_bits <= sizeof (T) * 8 );
191-
192- if constexpr (sizeof (T) > 4 && num_bits > 32 )
193- {
194- // If the given range is bigger than a word (32 bits)
195- value = 0 ;
196- uint32_t unsigned_value;
197-
198- BS_ASSERT (reader.serialize_bits (unsigned_value, 32 ));
199- value |= static_cast <T>(unsigned_value);
200-
201- BS_ASSERT (reader.serialize_bits (unsigned_value, num_bits - 32 ));
202- value |= static_cast <T>(unsigned_value) << 32 ;
203-
204- value += Min;
205- }
206- else
207- {
208- // If the given range is smaller than or equal to a word (32 bits)
209- uint32_t unsigned_value;
210- BS_ASSERT (reader.serialize_bits (unsigned_value, num_bits));
211-
212- value = static_cast <T>(unsigned_value) + Min;
213- }
214-
215- BS_ASSERT (value >= Min && value <= Max);
216-
217- return true ;
229+ return serialize_traits<bounded_int<T>>::serialize (stream, std::forward<U>(value));
218230 }
219231 };
220232#pragma endregion
0 commit comments