From 8ebb299176326332ad616689bd807eee2dc55b87 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Mon, 27 May 2024 20:17:20 -0600 Subject: [PATCH 01/17] Adding link, tweaking text --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93231e2..1a28614 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ The unit test code uses [Catch2](https://github.com/catchorg/Catch2). If the `SH The unit test uses utilities from Connective C++'s [utility-rack](https://github.com/connectivecpp/utility-rack). -Specific version (or branch) specs for the dependenies are in `test/CMakeLists.txt`. +Specific version (or branch) specs for the dependencies are in the [test/CMakeLists.txt](test/CMakeLists.txt) file, look for the `CPMAddPackage` commands. ## Build and Run Unit Tests From 13da715cfaf25573c2b9f68dec1e33cedf7a207e Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Fri, 31 May 2024 17:33:33 -0600 Subject: [PATCH 02/17] Adding Boost License shield to main README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1a28614..9a1bbad 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ ![GH Tag](https://img.shields.io/github/v/tag/connectivecpp/shared-buffer?label=GH%20tag) +![License](https://img.shields.io/badge/License-Boost%201.0-blue) + ## Overview The `shared_buffer` classes are reference counted `std::byte` buffer classes useful for asynchronous networking. In particular, the Asio asynchronous networking library requires a buffer to be kept alive and valid until the outstanding IO operation (e.g. a network write) is completed. A straightforward and idiomatic way to achieve this is by using reference counted buffers. From e13405ea25be39345fcd5e09a36e076c771ef197 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Mon, 10 Jun 2024 15:54:22 -0600 Subject: [PATCH 03/17] Adding missing const_shared_buffer span, revamped unit test --- include/buffer/shared_buffer.hpp | 118 +++++++++++---- test/shared_buffer_test.cpp | 242 +++++++++++++------------------ 2 files changed, 190 insertions(+), 170 deletions(-) diff --git a/include/buffer/shared_buffer.hpp b/include/buffer/shared_buffer.hpp index ad200fc..da6cb2d 100644 --- a/include/buffer/shared_buffer.hpp +++ b/include/buffer/shared_buffer.hpp @@ -81,12 +81,12 @@ #include #include // std::move, std::swap -#include // std::memcpy +#include // std::copy // TODO - add conecepts and / or requires // // modify the templated constructor that takes a buffer of any valid -// byte type, add constraints; this makes the "reinterpret_cast" safe +// byte type, add constraints which makes the casting safer namespace chops { @@ -147,6 +147,16 @@ class mutable_shared_buffer { mutable_shared_buffer() noexcept : m_data{std::make_shared(size_type(0))} { } +/** + * @brief Construct by copying from a @c std::span of @c std::byte. + * + * @param sp @c std::byte span pointing to buffer of data. The data is + * copied into the internal buffer of the @c mutable_shared_buffer. + * + */ + explicit mutable_shared_buffer(std::span sp) : + m_data{std::make_shared(sp.data(), sp.data()+sp.size())} { } + /** * @brief Move construct from a @c std::vector of @c std::bytes. * @@ -161,6 +171,7 @@ class mutable_shared_buffer { m_data{std::make_shared(size_type(0))} { *m_data = std::move(bv); } + /** * @brief Construct a @c mutable_shared_buffer with an initial size, contents * set to zero. @@ -171,18 +182,9 @@ class mutable_shared_buffer { * * @param sz Size for internal @c std::byte buffer. */ - explicit mutable_shared_buffer(size_type sz) noexcept : + explicit mutable_shared_buffer(size_type sz) : m_data{std::make_shared(sz)} { } -/** - * @brief Construct by copying from a @c std::span of @c std::byte. - * - * @param sp @c std::byte span pointing to buffer of data. The data is - * copied into the internal buffer of the @c mutable_shared_buffer. - * - */ - mutable_shared_buffer(std::span sp) noexcept : - m_data{std::make_shared(sp.data(), sp.data()+sp.size())} { } /** * @brief Construct by copying from a @c std::byte array. @@ -192,15 +194,29 @@ class mutable_shared_buffer { * * @pre Size cannot be greater than the source buffer. * - * @param buf @c std::byte array containing buffer of data. The data is - * copied into the internal buffer of the @c mutable_shared_buffer. + * @param buf Non-null pointer to a @c std::byte buffer of data. The + * data is copied into the internal buffer of the @c mutable_shared_buffer. * * @param sz Size of buffer. * */ - mutable_shared_buffer(const std::byte* buf, size_type sz) noexcept : + mutable_shared_buffer(const std::byte* buf, size_type sz) : mutable_shared_buffer(std::span(buf, sz)) { } +/** + * @brief Construct by copying bytes from a @c std::span. + * + * The type of the span must be convertible to or layout compatible with + * @c std::byte. + * + * @param sp @c std::span pointing to buffer of data. The @c std::span + * pointer is cast into a @c std::byte pointer and bytes are then copied. + * + */ + template + mutable_shared_buffer(std::span sp) : + mutable_shared_buffer(std::bit_cast(sp.data()), sp.size()) { } + /** * @brief Construct by copying bytes from an arbitrary pointer. * @@ -210,14 +226,13 @@ class mutable_shared_buffer { * * @pre Size cannot be greater than the source buffer. * - * @param buf Pointer to a buffer of data. The pointer must be convertible - * to a @c void pointer and then to a @c std::byte pointer. + * @param buf Non-null pointer to a buffer of data. * * @param sz Size of buffer, in bytes. */ template mutable_shared_buffer(const T* buf, size_type sz) : - mutable_shared_buffer(reinterpret_cast(buf), sz) { } + mutable_shared_buffer(std::bit_cast(buf), sz) { } /** * @brief Construct from input iterators. @@ -258,10 +273,10 @@ class mutable_shared_buffer { /** * @brief Return access to underlying @c std::vector. * - * This can be used to instantiate a dynamic_buffer as defined in the Networking TS. - * Changing the @c std::vector from outside this class works because no state - * data is stored within this object that needs to be consistent with the @c std::vector - * contents. + * This can be used to instantiate a @c dynamic_buffer as defined in the Networking TS + * or Asio API. Changing the @c std::vector from outside this class works because no + * state data is stored within this object that needs to be consistent with the + * @c std::vector contents. * * @return Reference to @c std::vector. */ @@ -315,7 +330,7 @@ class mutable_shared_buffer { /** * @brief Append a @c std::byte buffer to the end of the internal buffer. * - * @param buf @c std::byte array containing buffer of data. + * @param buf Non-null pointer to @c std::byte buffer of data. * * @param sz Size of buffer. * @@ -324,10 +339,21 @@ class mutable_shared_buffer { mutable_shared_buffer& append(const std::byte* buf, size_type sz) { size_type old_sz = size(); resize(old_sz + sz); // set up buffer space - std::memcpy(data() + old_sz, buf, sz); + std::copy(buf, buf+sz, data()+old_sz); return *this; } +/** + * @brief Append a @c std::span to the end of the internal buffer. + * + * @param sp @c std::span of @c std::byte data. + * + * @return Reference to @c this (to allow method chaining). + */ + mutable_shared_buffer& append(std::span sp) { + return append(sp.data(), sp.size()); + } + /** * @brief Append by copying bytes from an arbitrary pointer. * @@ -335,14 +361,31 @@ class mutable_shared_buffer { * are then copied. In particular, this method can be used for @c char pointers, * @c void pointers, @ unsigned @c char pointers, etc. * - * @param buf Pointer to a buffer of data. The pointer must be convertible - * to a @c void pointer and then to a @c std::byte pointer. + * @param buf Non-null pointer to a buffer of data. * * @param sz Size of buffer, in bytes. */ template mutable_shared_buffer& append(const T* buf, size_type sz) { - return append(reinterpret_cast(buf), sz); + return append(std::bit_cast(buf), sz); + } + +/** + * @brief Append a @c std::span that is a non @c std::byte buffer. + * + * The @c std::span passed into this method is performs a cast on the + * data. In particular, this method can be used for @c char pointers, + * @c void pointers, @ unsigned @c char pointers, etc. + * + * The type of the span must be convertible to or layout compatible with + * @c std::byte. + * + * @param sp @c std::span of arbitrary bytes. + * + */ + template + mutable_shared_buffer& append(std::span sp) { + return append(std::bit_cast(sp.data()), sp.size()); } /** @@ -463,18 +506,27 @@ class const_shared_buffer { const_shared_buffer& operator=(const const_shared_buffer&) = delete; const_shared_buffer& operator=(const_shared_buffer&&) = delete; +/** + * @brief Construct by copying from a @c std::span of @c std::byte. + * + * @param sp @c std::byte span pointing to buffer of data. The data is + * copied into the internal buffer of the @c const_shared_buffer. + * + */ + explicit const_shared_buffer(std::span sp) : + m_data(std::make_shared(sp.data(), sp.data()+sp.size())) { } /** * @brief Construct by copying from a @c std::byte array. * * @pre Size cannot be greater than the source buffer. * - * @param buf @c std::byte array containing buffer of data. The data is + * @param buf Non-null pointer to @c std::byte buffer of data. The data is * copied into the internal buffer of the @c const_shared_buffer. * * @param sz Size of buffer. */ const_shared_buffer(const std::byte* buf, size_type sz) : - m_data(std::make_shared(buf, buf+sz)) { } + const_shared_buffer(std::span(buf, sz)) { } /** * @brief Construct by copying bytes from an arbitrary pointer. @@ -483,16 +535,18 @@ class const_shared_buffer { * are then copied. In particular, this method can be used for @c char pointers, * @c void pointers, @c unsigned @c char pointers, etc. * + * The type of the span must be convertible to or layout compatible with + * @c std::byte. + * * @pre Size cannot be greater than the source buffer. * - * @param buf Pointer to a buffer of data. The pointer must be convertible - * to a @c void pointer and then to a @c std::byte pointer. + * @param buf Non-null pointer to a buffer of data. * * @param sz Size of buffer, in bytes. */ template const_shared_buffer(const T* buf, size_type sz) : - const_shared_buffer(reinterpret_cast(buf), sz) { } + const_shared_buffer(std::bit_cast(buf), sz) { } /** * @brief Construct by copying from a @c mutable_shared_buffer object. diff --git a/test/shared_buffer_test.cpp b/test/shared_buffer_test.cpp index d1445db..7e4a5f5 100644 --- a/test/shared_buffer_test.cpp +++ b/test/shared_buffer_test.cpp @@ -20,6 +20,7 @@ #include #include #include +#include // std::bit_cast #include "buffer/shared_buffer.hpp" @@ -33,7 +34,7 @@ constexpr int N = 11; template void generic_pointer_construction_test() { auto arr = chops::make_byte_array( 40, 41, 42, 43, 44, 60, 59, 58, 57, 56, 42, 42 ); - const PT* ptr = reinterpret_cast(arr.data()); + const PT* ptr = std::bit_cast(arr.data()); SB sb(ptr, arr.size()); REQUIRE_FALSE (sb.empty()); chops::repeat(static_cast(arr.size()), [&sb, arr] (int i) { REQUIRE(*(sb.data()+i) == arr[i]); } ); @@ -122,148 +123,120 @@ TEST_CASE ( "Mutable shared buffer copy construction and assignment", } } -SCENARIO ( "Mutable shared buffer resize and clear", - "[mutable_shared_buffer] [resize_and_clear]" ) { - - GIVEN ("A default constructed mutable shared_buffer") { - chops::mutable_shared_buffer sb; - WHEN ("Resize is called") { - sb.resize(N); - THEN ("the internal buffer will have all zeros") { - REQUIRE (sb.size() == N); - chops::repeat(N, [&sb] (const int& i) { REQUIRE (*(sb.data() + i) == std::byte{0} ); } ); - } - } - AND_WHEN ("Another mutable shared buffer with a size is constructed") { - sb.resize(N); - chops::mutable_shared_buffer sb2(N); - THEN ("the two shared buffers compare equal, with all zeros in the buffer") { - REQUIRE (sb == sb2); - chops::repeat(N, [&sb, &sb2] (const int& i) { - REQUIRE (*(sb.data() + i) == std::byte{0} ); - REQUIRE (*(sb2.data() + i) == std::byte{0} ); - } ); - } - } - AND_WHEN ("The mutable shared buffer is cleared") { - sb.resize(N); - sb.clear(); - THEN ("the size will be zero and the buffer is empty") { - REQUIRE (sb.size() == 0); - REQUIRE (sb.empty()); - } - } +TEST_CASE ( "Mutable shared buffer resize and clear", + "[mutable_shared_buffer] [resize_and_clear]" ) { + + chops::mutable_shared_buffer sb; + + sb.resize(N); + REQUIRE (sb.size() == N); + chops::repeat(N, [&sb] (int i) { REQUIRE (*(sb.data() + i) == std::byte{0} ); } ); + + SECTION ( "Compare two resized mutable shared buffer with same size" ) { + chops::mutable_shared_buffer sb2(N); + REQUIRE (sb == sb2); + chops::repeat(N, [&sb, &sb2] (int i) { + REQUIRE (*(sb.data() + i) == std::byte{0} ); + REQUIRE (*(sb2.data() + i) == std::byte{0} ); + } ); + } + SECTION ( "Clear, check size" ) { + sb.clear(); + REQUIRE (sb.size() == 0); + REQUIRE (sb.empty()); } // end given } -SCENARIO ( "Mutable shared buffer swap", - "[mutable_shared_buffer] [swap]" ) { - - GIVEN ("Two mutable shared_buffers") { - auto arr1 = chops::make_byte_array (0xaa, 0xbb, 0xcc); - auto arr2 = chops::make_byte_array (0x01, 0x02, 0x03, 0x04, 0x05); - - chops::mutable_shared_buffer sb1(arr1.cbegin(), arr1.cend()); - chops::mutable_shared_buffer sb2(arr2.cbegin(), arr2.cend()); - - WHEN ("The buffers are swapped") { - chops::swap(sb1, sb2); - THEN ("the sizes and contents will be swapped") { - REQUIRE (sb1.size() == arr2.size()); - REQUIRE (sb2.size() == arr1.size()); - REQUIRE (*(sb1.data()+0) == *(arr2.data()+0)); - REQUIRE (*(sb1.data()+1) == *(arr2.data()+1)); - REQUIRE (*(sb2.data()+0) == *(arr1.data()+0)); - REQUIRE (*(sb2.data()+1) == *(arr1.data()+1)); - } - } - } // end given +TEST_CASE ( "Mutable shared buffer swap", + "[mutable_shared_buffer] [swap]" ) { + + auto arr1 = chops::make_byte_array (0xaa, 0xbb, 0xcc); + auto arr2 = chops::make_byte_array (0x01, 0x02, 0x03, 0x04, 0x05); + + chops::mutable_shared_buffer sb1(arr1.cbegin(), arr1.cend()); + chops::mutable_shared_buffer sb2(arr2.cbegin(), arr2.cend()); + + chops::swap(sb1, sb2); + REQUIRE (sb1.size() == arr2.size()); + REQUIRE (sb2.size() == arr1.size()); + + REQUIRE (*(sb1.data()+0) == *(arr2.data()+0)); + REQUIRE (*(sb1.data()+1) == *(arr2.data()+1)); + REQUIRE (*(sb1.data()+2) == *(arr2.data()+2)); + REQUIRE (*(sb1.data()+3) == *(arr2.data()+3)); + REQUIRE (*(sb1.data()+4) == *(arr2.data()+4)); + + REQUIRE (*(sb2.data()+0) == *(arr1.data()+0)); + REQUIRE (*(sb2.data()+1) == *(arr1.data()+1)); + REQUIRE (*(sb2.data()+2) == *(arr1.data()+2)); } -SCENARIO ( "Mutable shared buffer append", - "[mutable_shared_buffer] [append]" ) { +TEST_CASE ( "Mutable shared buffer append", + "[mutable_shared_buffer] [append]" ) { auto arr = chops::make_byte_array (0xaa, 0xbb, 0xcc); auto arr2 = chops::make_byte_array (0xaa, 0xbb, 0xcc, 0xaa, 0xbb, 0xcc); chops::mutable_shared_buffer ta(arr.cbegin(), arr.cend()); chops::mutable_shared_buffer ta2(arr2.cbegin(), arr2.cend()); - GIVEN ("A default constructed mutable shared_buffer") { - chops::mutable_shared_buffer sb; - WHEN ("Append with a pointer and size is called") { - sb.append(arr.data(), arr.size()); - THEN ("the internal buffer will contain the appended data") { - REQUIRE (sb == ta); - } - } - AND_WHEN ("Append with a mutable shared buffer is called") { - sb.append(ta); - THEN ("the internal buffer will contain the appended data") { - REQUIRE (sb == ta); - } - } - AND_WHEN ("Append is called twice") { - sb.append(ta); - sb.append(ta); - THEN ("the internal buffer will contain twice the appended data") { - REQUIRE (sb == ta2); - } - } - AND_WHEN ("Appending with single bytes") { - sb.append(std::byte(0xaa)); - sb.append(std::byte(0xbb)); - sb += std::byte(0xcc); - THEN ("the internal buffer will contain the appended data") { - REQUIRE (sb == ta); - } - } - AND_WHEN ("Appending with a char* to test templated append") { - std::string_view sv("Haha, Bro!"); - chops::mutable_shared_buffer cb(sv.data(), sv.size()); - sb.append(sv.data(), sv.size()); - THEN ("the internal buffer will contain the appended data") { - REQUIRE (sb == cb); - } - } - } // end given + chops::mutable_shared_buffer sb; + REQUIRE (sb.empty()); + + SECTION ( "Append array to default constructed mutable shared_buffer" ) { + sb.append(arr.data(), arr.size()); + REQUIRE (sb == ta); + } + + SECTION ( "Append mutable shared buffer" ) { + sb.append(ta); + REQUIRE (sb == ta); + } + + SECTION ( "Call append twice" ) { + sb.append(ta); + sb.append(ta); + REQUIRE (sb == ta2); + } + + SECTION ( "Append with single byte" ) { + sb.append(std::byte(0xaa)); + sb.append(std::byte(0xbb)); + sb += std::byte(0xcc); + REQUIRE (sb == ta); + } + + SECTION ( "Append with templated append" ) { + std::string_view sv("Haha, Bro!"); + chops::mutable_shared_buffer cb(sv.data(), sv.size()); + sb.append(sv.data(), sv.size()); + REQUIRE (sb == cb); + } } -SCENARIO ( "Compare a mutable shared_buffer with a const shared buffer", - "[mutable_shared_buffer] [const_shared_buffer] [compare]" ) { - - GIVEN ("An array of bytes") { - auto arr = chops::make_byte_array (0xaa, 0xbb, 0xcc); - WHEN ("A mutable_shared_buffer and a const_shared_buffer are created from the bytes") { - chops::mutable_shared_buffer msb(arr.cbegin(), arr.cend()); - chops::const_shared_buffer csb(arr.cbegin(), arr.cend()); - THEN ("the shared buffers will compare equal") { - REQUIRE (msb == csb); - REQUIRE (csb == msb); - } - } - } // end given +TEST_CASE ( "Compare a mutable shared_buffer with a const shared buffer", + "[mutable_shared_buffer] [const_shared_buffer] [compare]" ) { + + auto arr = chops::make_byte_array (0xaa, 0xbb, 0xcc); + chops::mutable_shared_buffer msb(arr.cbegin(), arr.cend()); + chops::const_shared_buffer csb(arr.cbegin(), arr.cend()); + REQUIRE (msb == csb); + REQUIRE (csb == msb); } -SCENARIO ( "Mutable shared buffer move into const shared buffer", - "[mutable_shared_buffer] [const_shared_buffer] [move]" ) { +TEST_CASE ( "Mutable shared buffer move into const shared buffer", + "[mutable_shared_buffer] [const_shared_buffer] [move]" ) { auto arr1 = chops::make_byte_array (0xaa, 0xbb, 0xcc); auto arr2 = chops::make_byte_array (0x01, 0x02, 0x03, 0x04, 0x05); - GIVEN ("A mutable_shared_buffer") { - chops::mutable_shared_buffer msb(arr1.cbegin(), arr1.cend()); - WHEN ("A const_shared_buffer is move constructed from the mutable_shared_buffer") { - chops::const_shared_buffer csb(std::move(msb)); - THEN ("the const_shared_buffer will contain the data and the mutable_shared_buffer will not") { - REQUIRE (csb == chops::const_shared_buffer(arr1.cbegin(), arr1.cend())); - REQUIRE_FALSE (msb == csb); - msb.clear(); - msb.resize(arr2.size()); - msb.append(arr2.data(), arr2.size()); - REQUIRE_FALSE (msb == csb); - } - } - } // end given + chops::mutable_shared_buffer msb(arr1.cbegin(), arr1.cend()); + chops::const_shared_buffer csb(std::move(msb)); + REQUIRE (csb == chops::const_shared_buffer(arr1.cbegin(), arr1.cend())); + REQUIRE_FALSE (msb == csb); + msb.clear(); + msb.resize(arr2.size()); + msb.append(arr2.data(), arr2.size()); + REQUIRE_FALSE (msb == csb); } TEMPLATE_TEST_CASE ( "Move a vector of bytes into a shared buffer", @@ -274,24 +247,17 @@ TEMPLATE_TEST_CASE ( "Move a vector of bytes into a shared buffer", } -SCENARIO ( "Use get_byte_vec for external modification of buffer", - "[mutable_shared_buffer] [get_byte_vec]" ) { +TEST_CASE ( "Use get_byte_vec for external modification of buffer", + "[mutable_shared_buffer] [get_byte_vec]" ) { auto arr = chops::make_byte_array (0xaa, 0xbb, 0xcc); chops::mutable_shared_buffer::byte_vec bv (arr.cbegin(), arr.cend()); - GIVEN ("A mutable_shared_buffer") { - chops::mutable_shared_buffer msb(bv.cbegin(), bv.cend()); - - WHEN ("get_byte_vec is called") { - auto r = msb.get_byte_vec(); - THEN ("the refererence can be used to access and modify data") { - REQUIRE (r == bv); - r[0] = std::byte(0xdd); - REQUIRE_FALSE (r == bv); - } - } - } // end given + chops::mutable_shared_buffer msb(bv.cbegin(), bv.cend()); + auto r = msb.get_byte_vec(); + REQUIRE (r == bv); + r[0] = std::byte(0xdd); + REQUIRE_FALSE (r == bv); } From cac94b90b153cd845d8f096882624f5f8dfcad64 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Mon, 10 Jun 2024 16:44:41 -0600 Subject: [PATCH 04/17] Adding generic append test --- test/shared_buffer_test.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/test/shared_buffer_test.cpp b/test/shared_buffer_test.cpp index 7e4a5f5..17309b2 100644 --- a/test/shared_buffer_test.cpp +++ b/test/shared_buffer_test.cpp @@ -20,7 +20,7 @@ #include #include #include -#include // std::bit_cast +#include // std::bit_cast #include "buffer/shared_buffer.hpp" @@ -32,12 +32,24 @@ constexpr int N = 11; template -void generic_pointer_construction_test() { +SB generic_pointer_construction_test() { auto arr = chops::make_byte_array( 40, 41, 42, 43, 44, 60, 59, 58, 57, 56, 42, 42 ); - const PT* ptr = std::bit_cast(arr.data()); + auto ptr = std::bit_cast(arr.data()); SB sb(ptr, arr.size()); REQUIRE_FALSE (sb.empty()); chops::repeat(static_cast(arr.size()), [&sb, arr] (int i) { REQUIRE(*(sb.data()+i) == arr[i]); } ); + return sb; +} + +template +void generic_pointer_append_test() { + auto sb { generic_pointer_construction_test() }; + auto sav_sz { sb.size() }; + const PT arr[] { 5, 6, 7 }; + sb.append (arr, 3); + REQUIRE (sb.size() == (sav_sz + 3)); +// sb.append (std::span(arr, 3)); +// REQUIRE (sb.size() == (sav_sz + 6)); } template @@ -84,15 +96,15 @@ void byte_vector_move_test() { REQUIRE_FALSE (bv.size() == sb.size()); } -TEMPLATE_TEST_CASE ( "Checking generic pointer construction", +TEMPLATE_TEST_CASE ( "Generic pointer construction", "[common]", - char, unsigned char, signed char ) { + char, unsigned char, signed char, std::uint8_t ) { generic_pointer_construction_test(); generic_pointer_construction_test(); } -TEMPLATE_TEST_CASE ( "Shared buffer common methods test", +TEMPLATE_TEST_CASE ( "Shared buffer common methods", "[const_shared_buffer] [common]", chops::mutable_shared_buffer, chops::const_shared_buffer ) { auto arr = chops::make_byte_array ( 80, 81, 82, 83, 84, 90, 91, 92 ); @@ -213,6 +225,12 @@ TEST_CASE ( "Mutable shared buffer append", } } +TEMPLATE_TEST_CASE ( "Generic pointer append", + "[mutable_shared_buffer] [pointer] [append]", + char, unsigned char, signed char, std::uint8_t ) { + generic_pointer_append_test(); +} + TEST_CASE ( "Compare a mutable shared_buffer with a const shared buffer", "[mutable_shared_buffer] [const_shared_buffer] [compare]" ) { From d51bb5f17cb099fa6714091e7ccfb8265968598c Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Tue, 11 Jun 2024 18:30:21 -0600 Subject: [PATCH 05/17] Enhancing test with a little bit of span and generic pointer testing --- include/buffer/shared_buffer.hpp | 61 +++++++++++++++++--------------- test/shared_buffer_test.cpp | 8 +++-- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/include/buffer/shared_buffer.hpp b/include/buffer/shared_buffer.hpp index da6cb2d..d09ed08 100644 --- a/include/buffer/shared_buffer.hpp +++ b/include/buffer/shared_buffer.hpp @@ -154,9 +154,27 @@ class mutable_shared_buffer { * copied into the internal buffer of the @c mutable_shared_buffer. * */ - explicit mutable_shared_buffer(std::span sp) : + template + explicit mutable_shared_buffer(std::span sp) : m_data{std::make_shared(sp.data(), sp.data()+sp.size())} { } +/** + * @brief Construct by copying from a @c std::byte array. + * + * A @c std::span is first created, then the constructor taking + * a @c std::span is called. + * + * @pre Size cannot be greater than the source buffer. + * + * @param buf Non-null pointer to a @c std::byte buffer of data. The + * data is copied into the internal buffer of the @c mutable_shared_buffer. + * + * @param sz Size of buffer. + * + */ + mutable_shared_buffer(const std::byte* buf, size_type sz) : + mutable_shared_buffer(std::span(buf, sz)) { } + /** * @brief Move construct from a @c std::vector of @c std::bytes. * @@ -174,7 +192,7 @@ class mutable_shared_buffer { /** * @brief Construct a @c mutable_shared_buffer with an initial size, contents - * set to zero. + * of each byte set to zero. * * Allocate zero initialized space which can be overwritten with data as needed. * The @c data method is called to get access to the underlying @c std::byte @@ -186,35 +204,18 @@ class mutable_shared_buffer { m_data{std::make_shared(sz)} { } -/** - * @brief Construct by copying from a @c std::byte array. - * - * A @c std::span is first created, then the constructor taking - * a @c std::span is called. - * - * @pre Size cannot be greater than the source buffer. - * - * @param buf Non-null pointer to a @c std::byte buffer of data. The - * data is copied into the internal buffer of the @c mutable_shared_buffer. - * - * @param sz Size of buffer. - * - */ - mutable_shared_buffer(const std::byte* buf, size_type sz) : - mutable_shared_buffer(std::span(buf, sz)) { } - /** * @brief Construct by copying bytes from a @c std::span. * - * The type of the span must be convertible to or layout compatible with + * The type of the span must be convertible to or be layout compatible with * @c std::byte. * * @param sp @c std::span pointing to buffer of data. The @c std::span * pointer is cast into a @c std::byte pointer and bytes are then copied. * */ - template - mutable_shared_buffer(std::span sp) : + template + mutable_shared_buffer(std::span sp) : mutable_shared_buffer(std::bit_cast(sp.data()), sp.size()) { } /** @@ -350,7 +351,8 @@ class mutable_shared_buffer { * * @return Reference to @c this (to allow method chaining). */ - mutable_shared_buffer& append(std::span sp) { + template + mutable_shared_buffer& append(std::span sp) { return append(sp.data(), sp.size()); } @@ -377,14 +379,14 @@ class mutable_shared_buffer { * data. In particular, this method can be used for @c char pointers, * @c void pointers, @ unsigned @c char pointers, etc. * - * The type of the span must be convertible to or layout compatible with + * The type of the span must be convertible to or be layout compatible with * @c std::byte. * * @param sp @c std::span of arbitrary bytes. * */ - template - mutable_shared_buffer& append(std::span sp) { + template + mutable_shared_buffer& append(std::span sp) { return append(std::bit_cast(sp.data()), sp.size()); } @@ -513,7 +515,8 @@ class const_shared_buffer { * copied into the internal buffer of the @c const_shared_buffer. * */ - explicit const_shared_buffer(std::span sp) : + template + explicit const_shared_buffer(std::span sp) : m_data(std::make_shared(sp.data(), sp.data()+sp.size())) { } /** * @brief Construct by copying from a @c std::byte array. @@ -526,7 +529,7 @@ class const_shared_buffer { * @param sz Size of buffer. */ const_shared_buffer(const std::byte* buf, size_type sz) : - const_shared_buffer(std::span(buf, sz)) { } + const_shared_buffer(std::span{buf, buf+sz}) { } /** * @brief Construct by copying bytes from an arbitrary pointer. @@ -535,7 +538,7 @@ class const_shared_buffer { * are then copied. In particular, this method can be used for @c char pointers, * @c void pointers, @c unsigned @c char pointers, etc. * - * The type of the span must be convertible to or layout compatible with + * The type of the span must be convertible to or be layout compatible with * @c std::byte. * * @pre Size cannot be greater than the source buffer. diff --git a/test/shared_buffer_test.cpp b/test/shared_buffer_test.cpp index 17309b2..2d62540 100644 --- a/test/shared_buffer_test.cpp +++ b/test/shared_buffer_test.cpp @@ -46,10 +46,12 @@ void generic_pointer_append_test() { auto sb { generic_pointer_construction_test() }; auto sav_sz { sb.size() }; const PT arr[] { 5, 6, 7 }; - sb.append (arr, 3); + const PT* ptr_arr { arr }; + sb.append (ptr_arr, 3); REQUIRE (sb.size() == (sav_sz + 3)); -// sb.append (std::span(arr, 3)); -// REQUIRE (sb.size() == (sav_sz + 6)); + std::span sp { arr }; + sb.append (sp); + REQUIRE (sb.size() == (sav_sz + 6)); } template From 1f5f5c2f79887167b99e3c2e8f61350dee3aeff0 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Tue, 20 Aug 2024 16:31:24 -0600 Subject: [PATCH 06/17] Updating Catch2 version --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8f9b073..c0407ce 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,7 +15,7 @@ target_compile_features ( shared_buffer_test PRIVATE cxx_std_20 ) # add dependencies include ( ../cmake/download_cpm.cmake ) -CPMAddPackage ( "gh:catchorg/Catch2@3.6.0" ) +CPMAddPackage ( "gh:catchorg/Catch2@3.7.0" ) CPMAddPackage ( "gh:connectivecpp/utility-rack@1.0.0" ) # link dependencies From 18b0c5b27af9a8964dd8a298914c71f1854bd064 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Tue, 20 Aug 2024 16:34:01 -0600 Subject: [PATCH 07/17] Building on MSVC and macos --- .github/workflows/build_run_unit_test_cmake.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_run_unit_test_cmake.yml b/.github/workflows/build_run_unit_test_cmake.yml index 5f68d1a..0b832e0 100644 --- a/.github/workflows/build_run_unit_test_cmake.yml +++ b/.github/workflows/build_run_unit_test_cmake.yml @@ -12,8 +12,8 @@ jobs: build_matrix: strategy: matrix: - # os: [ubuntu-latest, windows-latest, macos-14] - os: [ubuntu-latest] + os: [ubuntu-latest, windows-latest, macos-14] + # os: [ubuntu-latest] runs-on: ${{ matrix.os }} defaults: run: From 74491fb714a8af3e52486aa85adfa1b2387792f6 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Tue, 20 Aug 2024 16:52:41 -0600 Subject: [PATCH 08/17] Building on MSVC --- .github/workflows/build_run_unit_test_cmake.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_run_unit_test_cmake.yml b/.github/workflows/build_run_unit_test_cmake.yml index 0b832e0..459bb7b 100644 --- a/.github/workflows/build_run_unit_test_cmake.yml +++ b/.github/workflows/build_run_unit_test_cmake.yml @@ -12,8 +12,8 @@ jobs: build_matrix: strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-14] - # os: [ubuntu-latest] + # os: [ubuntu-latest, windows-latest, macos-14] + os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} defaults: run: From 2c48ba6969d45306859ebb91f224c164fdc90798 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Tue, 20 Aug 2024 17:19:51 -0600 Subject: [PATCH 09/17] Adding Catch2 flag for std::byte formatting --- .github/workflows/build_run_unit_test_cmake.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_run_unit_test_cmake.yml b/.github/workflows/build_run_unit_test_cmake.yml index 459bb7b..6ca5992 100644 --- a/.github/workflows/build_run_unit_test_cmake.yml +++ b/.github/workflows/build_run_unit_test_cmake.yml @@ -12,8 +12,8 @@ jobs: build_matrix: strategy: matrix: - # os: [ubuntu-latest, windows-latest, macos-14] - os: [ubuntu-latest, windows-latest] + os: [ubuntu-latest, windows-latest, macos-14] + # os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} defaults: run: @@ -24,7 +24,7 @@ jobs: - name: create-build-dir run: mkdir build - name: configure-cmake - run: cd build && cmake -D SHARED_BUFFER_BUILD_TESTS:BOOL=ON -D SHARED_BUFFER_BUILD_EXAMPLES:BOOL=ON .. + run: cd build && cmake -D SHARED_BUFFER_BUILD_TESTS:BOOL=ON -D SHARED_BUFFER_BUILD_EXAMPLES:BOOL=ON -D CATCH_CONFIG_CPP17_BYTE:BOOL=ON .. - name: build run: cd build && cmake --build . --config $BUILD_TYPE - name: run-unit-test From ccc61f98a0086b3bdc676491739fd277ac672746 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Tue, 20 Aug 2024 17:23:55 -0600 Subject: [PATCH 10/17] Adding Catch2 flag for std::byte formatting, on MSVC (doesn't work on macos) --- .github/workflows/build_run_unit_test_cmake.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_run_unit_test_cmake.yml b/.github/workflows/build_run_unit_test_cmake.yml index 6ca5992..8817da8 100644 --- a/.github/workflows/build_run_unit_test_cmake.yml +++ b/.github/workflows/build_run_unit_test_cmake.yml @@ -12,8 +12,8 @@ jobs: build_matrix: strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-14] - # os: [ubuntu-latest, windows-latest] + # os: [ubuntu-latest, windows-latest, macos-14] + os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} defaults: run: From 5c62b421e0778166fb356ee7ecd89e345a62cf6f Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Thu, 22 Aug 2024 21:20:36 -0600 Subject: [PATCH 11/17] Enhanced span handling --- include/buffer/shared_buffer.hpp | 53 ++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/include/buffer/shared_buffer.hpp b/include/buffer/shared_buffer.hpp index d09ed08..3a2f095 100644 --- a/include/buffer/shared_buffer.hpp +++ b/include/buffer/shared_buffer.hpp @@ -83,7 +83,7 @@ #include // std::move, std::swap #include // std::copy -// TODO - add conecepts and / or requires +// TODO - add concepts and / or requires // // modify the templated constructor that takes a buffer of any valid // byte type, add constraints which makes the casting safer @@ -172,8 +172,8 @@ class mutable_shared_buffer { * @param sz Size of buffer. * */ - mutable_shared_buffer(const std::byte* buf, size_type sz) : - mutable_shared_buffer(std::span(buf, sz)) { } + mutable_shared_buffer(const std::byte* buf, std::size_t sz) : + mutable_shared_buffer(std::as_bytes(std::span{buf, sz})) { } /** * @brief Move construct from a @c std::vector of @c std::bytes. @@ -216,7 +216,7 @@ class mutable_shared_buffer { */ template mutable_shared_buffer(std::span sp) : - mutable_shared_buffer(std::bit_cast(sp.data()), sp.size()) { } + mutable_shared_buffer(std::as_bytes(sp)) { } /** * @brief Construct by copying bytes from an arbitrary pointer. @@ -233,7 +233,7 @@ class mutable_shared_buffer { */ template mutable_shared_buffer(const T* buf, size_type sz) : - mutable_shared_buffer(std::bit_cast(buf), sz) { } + mutable_shared_buffer(std::as_bytes(std::span{buf, sz})) { } /** * @brief Construct from input iterators. @@ -271,6 +271,13 @@ class mutable_shared_buffer { */ const std::byte* data() const noexcept { return m_data->data(); } +/** + * @brief Return size (number of bytes) of buffer. + * + * @return Size of buffer, which may be zero. + */ + size_type size() const noexcept { return m_data->size(); } + /** * @brief Return access to underlying @c std::vector. * @@ -283,13 +290,6 @@ class mutable_shared_buffer { */ byte_vec& get_byte_vec() noexcept { return *m_data; } -/** - * @brief Return size (number of bytes) of buffer. - * - * @return Size of buffer, which may be zero. - */ - size_type size() const noexcept { return m_data->size(); } - /** * @brief Query to see if size is zero. * @@ -337,7 +337,7 @@ class mutable_shared_buffer { * * @return Reference to @c this (to allow method chaining). */ - mutable_shared_buffer& append(const std::byte* buf, size_type sz) { + mutable_shared_buffer& append(const std::byte* buf, std::size_t sz) { size_type old_sz = size(); resize(old_sz + sz); // set up buffer space std::copy(buf, buf+sz, data()+old_sz); @@ -368,8 +368,8 @@ class mutable_shared_buffer { * @param sz Size of buffer, in bytes. */ template - mutable_shared_buffer& append(const T* buf, size_type sz) { - return append(std::bit_cast(buf), sz); + mutable_shared_buffer& append(const T* buf, std::size_t sz) { + return append(std::as_bytes(std::span{buf, sz})); } /** @@ -387,7 +387,7 @@ class mutable_shared_buffer { */ template mutable_shared_buffer& append(std::span sp) { - return append(std::bit_cast(sp.data()), sp.size()); + return append(std::as_bytes(sp)); } /** @@ -528,9 +528,22 @@ class const_shared_buffer { * * @param sz Size of buffer. */ - const_shared_buffer(const std::byte* buf, size_type sz) : - const_shared_buffer(std::span{buf, buf+sz}) { } + const_shared_buffer(const std::byte* buf, std::size_t sz) : + const_shared_buffer(std::as_bytes(std::span{buf, sz})) { } +/** + * @brief Construct by copying from a @c std::span. + * + * The type of the span must be convertible to or be layout compatible with + * @c std::byte. + * + * @param sp @c std::span pointing to buffer of data. The @c std::span + * pointer is cast into a @c std::byte pointer and bytes are then copied. + * + */ + template + const_shared_buffer(std::span sp) : + const_shared_buffer(std::as_bytes(sp)) { } /** * @brief Construct by copying bytes from an arbitrary pointer. * @@ -548,8 +561,8 @@ class const_shared_buffer { * @param sz Size of buffer, in bytes. */ template - const_shared_buffer(const T* buf, size_type sz) : - const_shared_buffer(std::bit_cast(buf), sz) { } + const_shared_buffer(const T* buf, std::size_t sz) : + const_shared_buffer(std::as_bytes(std::span{buf, sz})) { } /** * @brief Construct by copying from a @c mutable_shared_buffer object. From 717fb201381ee1b798b651cb7533ac4bb1056022 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Thu, 22 Aug 2024 21:21:11 -0600 Subject: [PATCH 12/17] Updated Catch2 and utility-rack versions --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c0407ce..5a72e14 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -16,7 +16,7 @@ target_compile_features ( shared_buffer_test PRIVATE cxx_std_20 ) include ( ../cmake/download_cpm.cmake ) CPMAddPackage ( "gh:catchorg/Catch2@3.7.0" ) -CPMAddPackage ( "gh:connectivecpp/utility-rack@1.0.0" ) +CPMAddPackage ( "gh:connectivecpp/utility-rack@1.0.3" ) # link dependencies target_link_libraries ( shared_buffer_test PRIVATE shared_buffer utility_rack Catch2::Catch2WithMain ) From c4009eb328ef5008258cf217d7e6ec1528bbcc42 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Thu, 22 Aug 2024 21:22:05 -0600 Subject: [PATCH 13/17] Enhancements to span and other functionality, changed byte compares to integer compares for Catch2 stringify weirdness on MSVC and macos --- test/shared_buffer_test.cpp | 149 +++++++++++++++++++++++++----------- 1 file changed, 104 insertions(+), 45 deletions(-) diff --git a/test/shared_buffer_test.cpp b/test/shared_buffer_test.cpp index 2d62540..0cd519c 100644 --- a/test/shared_buffer_test.cpp +++ b/test/shared_buffer_test.cpp @@ -20,24 +20,35 @@ #include #include #include +#include +#include // std::copy #include // std::bit_cast #include "buffer/shared_buffer.hpp" #include "utility/repeat.hpp" -#include "utility/make_byte_array.hpp" +#include "utility/byte_array.hpp" -constexpr std::byte Harhar { 42 }; -constexpr int N = 11; +constexpr std::size_t test_data_size { 12u }; +using test_data_type = std::array; +constexpr test_data_type test_data { chops::make_byte_array( 40, 41, 42, 43, 44, 60, 59, 58, 57, 56, 42, 42 ) }; +char test_data_char[test_data_size] { 40, 41, 42, 43, 44, 60, 59, 58, 57, 56, 42, 42 }; +const char* test_data_char_ptr {test_data_char}; +template +bool check_sb_against_test_data(SB sb) { + REQUIRE (sb.size() == test_data_size); + test_data_type buf; + std::copy(sb.data(), sb.data()+sb.size(), buf.begin()); + return chops::compare_byte_arrays(buf, test_data); +} template SB generic_pointer_construction_test() { - auto arr = chops::make_byte_array( 40, 41, 42, 43, 44, 60, 59, 58, 57, 56, 42, 42 ); - auto ptr = std::bit_cast(arr.data()); - SB sb(ptr, arr.size()); + auto ptr { std::bit_cast(test_data.data()) }; + SB sb(ptr, test_data_size); REQUIRE_FALSE (sb.empty()); - chops::repeat(static_cast(arr.size()), [&sb, arr] (int i) { REQUIRE(*(sb.data()+i) == arr[i]); } ); + REQUIRE (check_sb_against_test_data(sb)); return sb; } @@ -49,48 +60,85 @@ void generic_pointer_append_test() { const PT* ptr_arr { arr }; sb.append (ptr_arr, 3); REQUIRE (sb.size() == (sav_sz + 3)); - std::span sp { arr }; + std::span sp { arr }; sb.append (sp); REQUIRE (sb.size() == (sav_sz + 6)); } template -void common_methods_test(const std::byte* buf, typename SB::size_type sz) { +void check_sb(SB sb) { + REQUIRE_FALSE (sb.empty()); + REQUIRE (sb.size() == test_data_size); + REQUIRE (check_sb_against_test_data(sb)); +} - REQUIRE (sz > 2); +template +void common_ctor_test() { - SB sb(buf, sz); - REQUIRE_FALSE (sb.empty()); { - SB sb2(buf, sz); - REQUIRE_FALSE (sb2.empty()); - REQUIRE (sb == sb2); + std::span sp { test_data }; + SB sb{sp}; + check_sb(sb); } { - std::list lst (buf, buf+sz); - SB sb2(lst.cbegin(), lst.cend()); - REQUIRE_FALSE (sb2.empty()); - REQUIRE (sb == sb2); + std::span sp { test_data.data(), test_data.size() }; + SB sb{sp}; + check_sb(sb); } { - auto ba = chops::make_byte_array(buf[0], buf[1]); - SB sb2(ba.cbegin(), ba.cend()); - REQUIRE_FALSE (sb2.empty()); - REQUIRE (((sb2 < sb) != 0)); // uses spaceship operator - REQUIRE (sb2 != sb); + SB sb{test_data.data(), test_data.size()}; + check_sb(sb); } { - auto ba = chops::make_byte_array(0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - SB sb2(ba.cbegin(), ba.cend()); - REQUIRE_FALSE (sb2.empty()); - REQUIRE (sb2 != sb); + std::span sp { test_data_char }; + SB sb{sp}; + check_sb(sb); + } + { + std::span sp { test_data_char, test_data_char+test_data_size }; + SB sb{sp}; + check_sb(sb); + } + { + SB sb{test_data_char_ptr, test_data_size}; + check_sb(sb); + } + + { + std::list lst {test_data.cbegin(), test_data.cend()}; + SB sb {lst.cbegin(), lst.cend()}; + check_sb(sb); } + { + SB sb1{test_data.data(), test_data.size()}; + SB sb2{test_data.data(), test_data.size()}; + REQUIRE (sb1 == sb2); + } + { + SB sb1{test_data.data(), test_data.size()}; + SB sb2{sb1}; + REQUIRE (sb1 == sb2); + } + +} + +template +void common_comparison_test() { + auto ba1 { chops::make_byte_array(0x00, 0x00, 0x00) }; + auto ba2 { chops::make_byte_array(0x00, 0x22, 0x33) }; + + SB sb1(ba1.cbegin(), ba1.cend()); + SB sb2(ba2.cbegin(), ba2.cend()); + REQUIRE_FALSE (sb1.empty()); + REQUIRE_FALSE (sb2.empty()); + REQUIRE_FALSE (sb1 == sb2); + REQUIRE (((sb1 < sb2) != 0)); // uses spaceship operator } template void byte_vector_move_test() { - auto arr = chops::make_byte_array (0x01, 0x02, 0x03, 0x04, 0x05); + auto arr { chops::make_byte_array (0x01, 0x02, 0x03, 0x04, 0x05) }; std::vector bv { arr.cbegin(), arr.cend() }; SB sb(std::move(bv)); @@ -106,17 +154,24 @@ TEMPLATE_TEST_CASE ( "Generic pointer construction", } -TEMPLATE_TEST_CASE ( "Shared buffer common methods", - "[const_shared_buffer] [common]", +TEMPLATE_TEST_CASE ( "Shared buffer common ctor methods", + "[const_shared_buffer] [mutable_shared_buffer] [common]", + chops::mutable_shared_buffer, chops::const_shared_buffer ) { + common_ctor_test(); +} + +TEMPLATE_TEST_CASE ( "Shared buffer common comparison methods", + "[const_shared_buffer] [mutable_shared_buffer] [common]", chops::mutable_shared_buffer, chops::const_shared_buffer ) { - auto arr = chops::make_byte_array ( 80, 81, 82, 83, 84, 90, 91, 92 ); - common_methods_test(arr.data(), arr.size()); + common_comparison_test(); } TEST_CASE ( "Mutable shared buffer copy construction and assignment", "[mutable_shared_buffer] [copy]" ) { - auto arr = chops::make_byte_array ( 80, 81, 82, 83, 84, 90, 91, 92 ); + constexpr std::byte Harhar { 42 }; + + auto arr { chops::make_byte_array ( 80, 81, 82, 83, 84, 90, 91, 92 ) }; chops::mutable_shared_buffer sb; REQUIRE (sb.empty()); @@ -140,18 +195,22 @@ TEST_CASE ( "Mutable shared buffer copy construction and assignment", TEST_CASE ( "Mutable shared buffer resize and clear", "[mutable_shared_buffer] [resize_and_clear]" ) { + constexpr int N = 11; + chops::mutable_shared_buffer sb; + REQUIRE (sb.empty()); + REQUIRE (sb.size() == 0); sb.resize(N); REQUIRE (sb.size() == N); - chops::repeat(N, [&sb] (int i) { REQUIRE (*(sb.data() + i) == std::byte{0} ); } ); + chops::repeat(N, [&sb] (int i) { REQUIRE (std::to_integer(*(sb.data() + i)) == 0 ); } ); SECTION ( "Compare two resized mutable shared buffer with same size" ) { chops::mutable_shared_buffer sb2(N); REQUIRE (sb == sb2); chops::repeat(N, [&sb, &sb2] (int i) { - REQUIRE (*(sb.data() + i) == std::byte{0} ); - REQUIRE (*(sb2.data() + i) == std::byte{0} ); + REQUIRE (std::to_integer(*(sb.data() + i)) == 0 ); + REQUIRE (std::to_integer(*(sb2.data() + i)) == 0 ); } ); } SECTION ( "Clear, check size" ) { @@ -174,15 +233,15 @@ TEST_CASE ( "Mutable shared buffer swap", REQUIRE (sb1.size() == arr2.size()); REQUIRE (sb2.size() == arr1.size()); - REQUIRE (*(sb1.data()+0) == *(arr2.data()+0)); - REQUIRE (*(sb1.data()+1) == *(arr2.data()+1)); - REQUIRE (*(sb1.data()+2) == *(arr2.data()+2)); - REQUIRE (*(sb1.data()+3) == *(arr2.data()+3)); - REQUIRE (*(sb1.data()+4) == *(arr2.data()+4)); + REQUIRE (std::to_integer(*(sb1.data()+0)) == std::to_integer(*(arr2.data()+0))); + REQUIRE (std::to_integer(*(sb1.data()+1)) == std::to_integer(*(arr2.data()+1))); + REQUIRE (std::to_integer(*(sb1.data()+2)) == std::to_integer(*(arr2.data()+2))); + REQUIRE (std::to_integer(*(sb1.data()+3)) == std::to_integer(*(arr2.data()+3))); + REQUIRE (std::to_integer(*(sb1.data()+4)) == std::to_integer(*(arr2.data()+4))); - REQUIRE (*(sb2.data()+0) == *(arr1.data()+0)); - REQUIRE (*(sb2.data()+1) == *(arr1.data()+1)); - REQUIRE (*(sb2.data()+2) == *(arr1.data()+2)); + REQUIRE (std::to_integer(*(sb2.data()+0)) == std::to_integer(*(arr1.data()+0))); + REQUIRE (std::to_integer(*(sb2.data()+1)) == std::to_integer(*(arr1.data()+1))); + REQUIRE (std::to_integer(*(sb2.data()+2)) == std::to_integer(*(arr1.data()+2))); } TEST_CASE ( "Mutable shared buffer append", From 98d2bdd462902845d3c874c72c38e9c2bbfb37f4 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Thu, 22 Aug 2024 21:25:27 -0600 Subject: [PATCH 14/17] Removing Catch2 byte flag --- .github/workflows/build_run_unit_test_cmake.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_run_unit_test_cmake.yml b/.github/workflows/build_run_unit_test_cmake.yml index 8817da8..459bb7b 100644 --- a/.github/workflows/build_run_unit_test_cmake.yml +++ b/.github/workflows/build_run_unit_test_cmake.yml @@ -24,7 +24,7 @@ jobs: - name: create-build-dir run: mkdir build - name: configure-cmake - run: cd build && cmake -D SHARED_BUFFER_BUILD_TESTS:BOOL=ON -D SHARED_BUFFER_BUILD_EXAMPLES:BOOL=ON -D CATCH_CONFIG_CPP17_BYTE:BOOL=ON .. + run: cd build && cmake -D SHARED_BUFFER_BUILD_TESTS:BOOL=ON -D SHARED_BUFFER_BUILD_EXAMPLES:BOOL=ON .. - name: build run: cd build && cmake --build . --config $BUILD_TYPE - name: run-unit-test From ea0c3d633a1c92cf77e3bd9f4a55fe27b8d85a2b Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Thu, 22 Aug 2024 21:34:44 -0600 Subject: [PATCH 15/17] Workaround Catch2 problems with std::byte --- test/shared_buffer_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/shared_buffer_test.cpp b/test/shared_buffer_test.cpp index 0cd519c..b64e55a 100644 --- a/test/shared_buffer_test.cpp +++ b/test/shared_buffer_test.cpp @@ -335,8 +335,8 @@ TEST_CASE ( "Use get_byte_vec for external modification of buffer", chops::mutable_shared_buffer msb(bv.cbegin(), bv.cend()); auto r = msb.get_byte_vec(); - REQUIRE (r == bv); +// REQUIRE (r == bv); // Catch2 build problems on MSVC r[0] = std::byte(0xdd); - REQUIRE_FALSE (r == bv); +// REQUIRE_FALSE (r == bv); // Catch2 build problems on MSVC } From 50a41ba0c8251755420d2611a86859118ba8861d Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Thu, 22 Aug 2024 21:43:16 -0600 Subject: [PATCH 16/17] Workaround Catch2 problems with std::byte --- test/shared_buffer_test.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/shared_buffer_test.cpp b/test/shared_buffer_test.cpp index b64e55a..4776df7 100644 --- a/test/shared_buffer_test.cpp +++ b/test/shared_buffer_test.cpp @@ -336,7 +336,11 @@ TEST_CASE ( "Use get_byte_vec for external modification of buffer", auto r = msb.get_byte_vec(); // REQUIRE (r == bv); // Catch2 build problems on MSVC + std::array arr2 { r[0], r[1], r[2] }; + REQUIRE (chops::compare_byte_arrays(arr, arr2)); r[0] = std::byte(0xdd); // REQUIRE_FALSE (r == bv); // Catch2 build problems on MSVC + std::array arr3 { r[0], r[1], r[2] }; + REQUIRE_FALSE (chops::compare_byte_arrays(arr, arr3)); } From 9d20c02bc6df2d2b53c2f97ffbccd4b28a1c3002 Mon Sep 17 00:00:00 2001 From: cliffg-softwarelibre Date: Thu, 22 Aug 2024 21:45:41 -0600 Subject: [PATCH 17/17] Adding macos back to matrix --- .github/workflows/build_run_unit_test_cmake.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_run_unit_test_cmake.yml b/.github/workflows/build_run_unit_test_cmake.yml index 459bb7b..311762a 100644 --- a/.github/workflows/build_run_unit_test_cmake.yml +++ b/.github/workflows/build_run_unit_test_cmake.yml @@ -12,8 +12,8 @@ jobs: build_matrix: strategy: matrix: - # os: [ubuntu-latest, windows-latest, macos-14] - os: [ubuntu-latest, windows-latest] + os: [ubuntu-latest, windows-latest, macos-14] + # os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} defaults: run: