@@ -144,11 +144,27 @@ concept supports_expandable_buffer =
144
144
{ ctr.data () } -> std::same_as<std::byte*>;
145
145
}
146
146
147
+ template <typename Ctr>
148
+ concept supports_endian_expandable_buffer =
149
+ supports_expandable_buffer<Ctr> &&
150
+ requires (Ctr ctr) {
151
+ typename Ctr::endian_type;
152
+ }
153
+
147
154
template <supports_expandable_buffer Ctr = chops::mutable_shared_buffer,
148
155
std::endian Endian = std::endian::little>
149
- struct expandable_buffer : Ctr {
150
- using Endian;
151
- }
156
+ class expandable_buffer {
157
+ private:
158
+ Ctr m_ctr;
159
+ public:
160
+ using endian_type = Endian;
161
+ using value_type = std::byte;
162
+ Ctr& get_buf () noexcept { return m_ctr; }
163
+ std::size_t size () noexcept { return m_ctr.size (); }
164
+ std::byte* data () noexcept { return m_ctr.data (); }
165
+ void resize (std::size_t sz) noexcept m_ctr.resize(sz); }
166
+ };
167
+
152
168
/* *
153
169
154
170
* @brief Extract a sequence in network byte order from a @c std::byte buffer into the
@@ -286,29 +302,55 @@ class fixed_size_byte_array {
286
302
// similar can be used for the Buf template parameter
287
303
struct adl_tag { };
288
304
289
- // lower-level function template that performs the actual buffer manipulation and
290
- // marshalling of a single value, with an ADL tag for full namespace inclusion in the
291
- // overload set; this function template is not called directly by application code, and
292
- // is only used with arithmetic values or a std::byte
293
- template <typename CastValType, typename T, typename Buf = chops::mutable_shared_buffer>
294
- Buf& marshall (Buf& buf, const T& val, adl_tag) {
295
- auto old_sz = buf.size ();
296
- buf.resize (old_sz + sizeof (CastValType));
297
- append_val (buf.data ()+old_sz, static_cast <CastValType>(val));
298
- return buf;
299
- }
300
305
301
306
namespace detail {
302
307
303
- template <typename CastValType, typename T, typename Buf = expandable_buffer>
308
+ template <integral_or_byte CastTypeVal, integral_or_byte T,
309
+ supports_endian_expandable_buf Buf = expandable_buffer>
304
310
constexpr Buf& serialize_val (Buf& buf, const T& val) {
305
311
auto old_sz = buf.size ();
306
- buf.resize (old_sz + sizeof (CastValType));
307
- append_val (buf.data ()+old_sz, static_cast <CastValType>(val));
312
+ buf.resize (old_sz + sizeof (CastTypeVal));
313
+ append_val<Buf::endian_type>(buf.data ()+old_sz, static_cast <CastTypeVal>(val));
314
+ return buf;
315
+ }
316
+
317
+ template <integral_or_byte CastTypeVal, integral_or_byte T,
318
+ supports_endian_expandable Buf = chops::mutable_shared_buffer>
319
+ constexpr Buf& serialize (Buf& buf, const T& val) {
320
+ return serialize_val<CastTypeVal> (buf, val);
321
+ }
322
+
323
+ template <integral_or_byte CastTypeSz, integral_or_byte CastTypeVal,
324
+ integral_or_byte T,
325
+ supports_endian_expandable Buf = chops::mutable_shared_buffer>
326
+ constexpr Buf& serialize (Buf& buf, const T* seq, std::size_t sz) {
327
+ serialize_val<CastTypeSz> (buf, sz);
328
+ for (int i {0 }; i < sz; ++i) {
329
+ serialize_val<CastTypeVal>(buf, seq[i]);
330
+ }
308
331
return buf;
309
332
}
310
333
334
+ template <integral_or_byte CastTypeSz,
335
+ supports_endian_expandable Buf = chops::mutable_shared_buffer>
336
+ constexpr Buf& serialize (Buf& buf, const std::string& str) {
337
+ return serialize<CastTypeSz, std::byte> (buf, str.data (), std.size ());
338
+ }
339
+
340
+ template <integral_or_byte CastTypeBool, integral_or_byte CastTypeVal,
341
+ integral_or_byte T,
342
+ supports_endian_expandable Buf = chops::mutable_shared_buffer>
343
+ constexpr Buf& serialize (Buf& buf, const std::optional<T>& val) {
344
+ if (val)
345
+ serialize_val<CastTypeBool> (buf, 1 );
346
+ return serialize_val<CastTypeVal> (buf, *val);
347
+ }
348
+ serialize_val<CastTypeBool> (buf, 0 );
349
+ }
350
+
311
351
}
352
+
353
+
312
354
/* *
313
355
* @brief Marshall a single arithmetic value or a @c std::byte into a buffer of bytes.
314
356
*
0 commit comments