Skip to content

Commit e13405e

Browse files
Adding missing const_shared_buffer span, revamped unit test
1 parent 13da715 commit e13405e

File tree

2 files changed

+190
-170
lines changed

2 files changed

+190
-170
lines changed

include/buffer/shared_buffer.hpp

Lines changed: 86 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,12 @@
8181
#include <span>
8282

8383
#include <utility> // std::move, std::swap
84-
#include <cstring> // std::memcpy
84+
#include <algorithm> // std::copy
8585

8686
// TODO - add conecepts and / or requires
8787
//
8888
// modify the templated constructor that takes a buffer of any valid
89-
// byte type, add constraints; this makes the "reinterpret_cast" safe
89+
// byte type, add constraints which makes the casting safer
9090

9191
namespace chops {
9292

@@ -147,6 +147,16 @@ class mutable_shared_buffer {
147147
mutable_shared_buffer() noexcept :
148148
m_data{std::make_shared<byte_vec>(size_type(0))} { }
149149

150+
/**
151+
* @brief Construct by copying from a @c std::span of @c std::byte.
152+
*
153+
* @param sp @c std::byte span pointing to buffer of data. The data is
154+
* copied into the internal buffer of the @c mutable_shared_buffer.
155+
*
156+
*/
157+
explicit mutable_shared_buffer(std::span<const std::byte> sp) :
158+
m_data{std::make_shared<byte_vec>(sp.data(), sp.data()+sp.size())} { }
159+
150160
/**
151161
* @brief Move construct from a @c std::vector of @c std::bytes.
152162
*
@@ -161,6 +171,7 @@ class mutable_shared_buffer {
161171
m_data{std::make_shared<byte_vec>(size_type(0))} {
162172
*m_data = std::move(bv);
163173
}
174+
164175
/**
165176
* @brief Construct a @c mutable_shared_buffer with an initial size, contents
166177
* set to zero.
@@ -171,18 +182,9 @@ class mutable_shared_buffer {
171182
*
172183
* @param sz Size for internal @c std::byte buffer.
173184
*/
174-
explicit mutable_shared_buffer(size_type sz) noexcept :
185+
explicit mutable_shared_buffer(size_type sz) :
175186
m_data{std::make_shared<byte_vec>(sz)} { }
176187

177-
/**
178-
* @brief Construct by copying from a @c std::span of @c std::byte.
179-
*
180-
* @param sp @c std::byte span pointing to buffer of data. The data is
181-
* copied into the internal buffer of the @c mutable_shared_buffer.
182-
*
183-
*/
184-
mutable_shared_buffer(std::span<const std::byte> sp) noexcept :
185-
m_data{std::make_shared<byte_vec>(sp.data(), sp.data()+sp.size())} { }
186188

187189
/**
188190
* @brief Construct by copying from a @c std::byte array.
@@ -192,15 +194,29 @@ class mutable_shared_buffer {
192194
*
193195
* @pre Size cannot be greater than the source buffer.
194196
*
195-
* @param buf @c std::byte array containing buffer of data. The data is
196-
* copied into the internal buffer of the @c mutable_shared_buffer.
197+
* @param buf Non-null pointer to a @c std::byte buffer of data. The
198+
* data is copied into the internal buffer of the @c mutable_shared_buffer.
197199
*
198200
* @param sz Size of buffer.
199201
*
200202
*/
201-
mutable_shared_buffer(const std::byte* buf, size_type sz) noexcept :
203+
mutable_shared_buffer(const std::byte* buf, size_type sz) :
202204
mutable_shared_buffer(std::span<const std::byte>(buf, sz)) { }
203205

206+
/**
207+
* @brief Construct by copying bytes from a @c std::span.
208+
*
209+
* The type of the span must be convertible to or layout compatible with
210+
* @c std::byte.
211+
*
212+
* @param sp @c std::span pointing to buffer of data. The @c std::span
213+
* pointer is cast into a @c std::byte pointer and bytes are then copied.
214+
*
215+
*/
216+
template <typename T>
217+
mutable_shared_buffer(std::span<const T> sp) :
218+
mutable_shared_buffer(std::bit_cast<const std::byte *>(sp.data()), sp.size()) { }
219+
204220
/**
205221
* @brief Construct by copying bytes from an arbitrary pointer.
206222
*
@@ -210,14 +226,13 @@ class mutable_shared_buffer {
210226
*
211227
* @pre Size cannot be greater than the source buffer.
212228
*
213-
* @param buf Pointer to a buffer of data. The pointer must be convertible
214-
* to a @c void pointer and then to a @c std::byte pointer.
229+
* @param buf Non-null pointer to a buffer of data.
215230
*
216231
* @param sz Size of buffer, in bytes.
217232
*/
218233
template <typename T>
219234
mutable_shared_buffer(const T* buf, size_type sz) :
220-
mutable_shared_buffer(reinterpret_cast<const std::byte *>(buf), sz) { }
235+
mutable_shared_buffer(std::bit_cast<const std::byte *>(buf), sz) { }
221236

222237
/**
223238
* @brief Construct from input iterators.
@@ -258,10 +273,10 @@ class mutable_shared_buffer {
258273
/**
259274
* @brief Return access to underlying @c std::vector.
260275
*
261-
* This can be used to instantiate a dynamic_buffer as defined in the Networking TS.
262-
* Changing the @c std::vector from outside this class works because no state
263-
* data is stored within this object that needs to be consistent with the @c std::vector
264-
* contents.
276+
* This can be used to instantiate a @c dynamic_buffer as defined in the Networking TS
277+
* or Asio API. Changing the @c std::vector from outside this class works because no
278+
* state data is stored within this object that needs to be consistent with the
279+
* @c std::vector contents.
265280
*
266281
* @return Reference to @c std::vector<std::byte>.
267282
*/
@@ -315,7 +330,7 @@ class mutable_shared_buffer {
315330
/**
316331
* @brief Append a @c std::byte buffer to the end of the internal buffer.
317332
*
318-
* @param buf @c std::byte array containing buffer of data.
333+
* @param buf Non-null pointer to @c std::byte buffer of data.
319334
*
320335
* @param sz Size of buffer.
321336
*
@@ -324,25 +339,53 @@ class mutable_shared_buffer {
324339
mutable_shared_buffer& append(const std::byte* buf, size_type sz) {
325340
size_type old_sz = size();
326341
resize(old_sz + sz); // set up buffer space
327-
std::memcpy(data() + old_sz, buf, sz);
342+
std::copy(buf, buf+sz, data()+old_sz);
328343
return *this;
329344
}
330345

346+
/**
347+
* @brief Append a @c std::span to the end of the internal buffer.
348+
*
349+
* @param sp @c std::span of @c std::byte data.
350+
*
351+
* @return Reference to @c this (to allow method chaining).
352+
*/
353+
mutable_shared_buffer& append(std::span<const std::byte> sp) {
354+
return append(sp.data(), sp.size());
355+
}
356+
331357
/**
332358
* @brief Append by copying bytes from an arbitrary pointer.
333359
*
334360
* The pointer passed into this method is cast into a @c std::byte pointer and bytes
335361
* are then copied. In particular, this method can be used for @c char pointers,
336362
* @c void pointers, @ unsigned @c char pointers, etc.
337363
*
338-
* @param buf Pointer to a buffer of data. The pointer must be convertible
339-
* to a @c void pointer and then to a @c std::byte pointer.
364+
* @param buf Non-null pointer to a buffer of data.
340365
*
341366
* @param sz Size of buffer, in bytes.
342367
*/
343368
template <typename T>
344369
mutable_shared_buffer& append(const T* buf, size_type sz) {
345-
return append(reinterpret_cast<const std::byte *>(buf), sz);
370+
return append(std::bit_cast<const std::byte *>(buf), sz);
371+
}
372+
373+
/**
374+
* @brief Append a @c std::span that is a non @c std::byte buffer.
375+
*
376+
* The @c std::span passed into this method is performs a cast on the
377+
* data. In particular, this method can be used for @c char pointers,
378+
* @c void pointers, @ unsigned @c char pointers, etc.
379+
*
380+
* The type of the span must be convertible to or layout compatible with
381+
* @c std::byte.
382+
*
383+
* @param sp @c std::span of arbitrary bytes.
384+
*
385+
*/
386+
template <typename T>
387+
mutable_shared_buffer& append(std::span<const T> sp) {
388+
return append(std::bit_cast<const std::byte *>(sp.data()), sp.size());
346389
}
347390

348391
/**
@@ -463,18 +506,27 @@ class const_shared_buffer {
463506
const_shared_buffer& operator=(const const_shared_buffer&) = delete;
464507
const_shared_buffer& operator=(const_shared_buffer&&) = delete;
465508

509+
/**
510+
* @brief Construct by copying from a @c std::span of @c std::byte.
511+
*
512+
* @param sp @c std::byte span pointing to buffer of data. The data is
513+
* copied into the internal buffer of the @c const_shared_buffer.
514+
*
515+
*/
516+
explicit const_shared_buffer(std::span<const std::byte> sp) :
517+
m_data(std::make_shared<byte_vec>(sp.data(), sp.data()+sp.size())) { }
466518
/**
467519
* @brief Construct by copying from a @c std::byte array.
468520
*
469521
* @pre Size cannot be greater than the source buffer.
470522
*
471-
* @param buf @c std::byte array containing buffer of data. The data is
523+
* @param buf Non-null pointer to @c std::byte buffer of data. The data is
472524
* copied into the internal buffer of the @c const_shared_buffer.
473525
*
474526
* @param sz Size of buffer.
475527
*/
476528
const_shared_buffer(const std::byte* buf, size_type sz) :
477-
m_data(std::make_shared<byte_vec>(buf, buf+sz)) { }
529+
const_shared_buffer(std::span<const std::byte>(buf, sz)) { }
478530

479531
/**
480532
* @brief Construct by copying bytes from an arbitrary pointer.
@@ -483,16 +535,18 @@ class const_shared_buffer {
483535
* are then copied. In particular, this method can be used for @c char pointers,
484536
* @c void pointers, @c unsigned @c char pointers, etc.
485537
*
538+
* The type of the span must be convertible to or layout compatible with
539+
* @c std::byte.
540+
*
486541
* @pre Size cannot be greater than the source buffer.
487542
*
488-
* @param buf Pointer to a buffer of data. The pointer must be convertible
489-
* to a @c void pointer and then to a @c std::byte pointer.
543+
* @param buf Non-null pointer to a buffer of data.
490544
*
491545
* @param sz Size of buffer, in bytes.
492546
*/
493547
template <typename T>
494548
const_shared_buffer(const T* buf, size_type sz) :
495-
const_shared_buffer(reinterpret_cast<const std::byte *>(buf), sz) { }
549+
const_shared_buffer(std::bit_cast<const std::byte *>(buf), sz) { }
496550

497551
/**
498552
* @brief Construct by copying from a @c mutable_shared_buffer object.

0 commit comments

Comments
 (0)