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
9191namespace 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