]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
enhance: Add more util::Bytes constructor and operator= variants
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 25 Oct 2025 14:26:28 +0000 (16:26 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 25 Oct 2025 21:15:57 +0000 (23:15 +0200)
src/ccache/util/bytes.cpp
src/ccache/util/bytes.hpp
unittest/test_util_bytes.cpp

index b3e01fee3e27b0e6ae0cac7e7bb7d536276bc34a..4856d184d1bbb1fe442bbe3a39af1aaf24d86c4f 100644 (file)
 
 namespace util {
 
+namespace {
+
+void
+assign_from_data(Bytes* bytes, const void* data, size_t size) noexcept
+{
+  bytes->resize(size);
+  if (size > 0) {
+    std::memcpy(bytes->data(), data, size);
+  }
+}
+
+} // namespace
+
 Bytes::Bytes(const Bytes& other) noexcept
   : m_data(std::make_unique<uint8_t[]>(other.m_size)),
     m_size(other.m_size),
@@ -48,12 +61,7 @@ Bytes::operator=(const Bytes& other) noexcept
   if (&other == this) {
     return *this;
   }
-  m_data = std::make_unique<uint8_t[]>(other.m_size);
-  m_size = other.m_size;
-  m_capacity = other.m_size;
-  if (m_size > 0) {
-    std::memcpy(m_data.get(), other.m_data.get(), m_size);
-  }
+  assign_from_data(this, other.m_data.get(), other.m_size);
   return *this;
 }
 
@@ -72,6 +80,20 @@ Bytes::operator=(Bytes&& other) noexcept
   return *this;
 }
 
+Bytes&
+Bytes::operator=(nonstd::span<const uint8_t> data) noexcept
+{
+  assign_from_data(this, data.data(), data.size());
+  return *this;
+}
+
+Bytes&
+Bytes::operator=(std::string_view data) noexcept
+{
+  assign_from_data(this, data.data(), data.size());
+  return *this;
+}
+
 void
 Bytes::reserve(size_t size) noexcept
 {
index c44da78ee7c881b21791c5e937c40baf0849db2d..d7545e2a57944d010734057a9ddece124ecdd46c 100644 (file)
@@ -24,6 +24,7 @@
 #include <cstring>
 #include <initializer_list>
 #include <memory>
+#include <string_view>
 
 namespace util {
 
@@ -40,7 +41,9 @@ public:
   explicit Bytes(size_t size) noexcept;
 
   Bytes(const void* data, size_t size) noexcept;
+  Bytes(const void* first, const void* last) noexcept;
   Bytes(nonstd::span<const uint8_t> data) noexcept;
+  Bytes(std::string_view data) noexcept;
 
   Bytes(const Bytes& other) noexcept;
   Bytes(Bytes&& other) noexcept;
@@ -51,6 +54,8 @@ public:
 
   Bytes& operator=(const Bytes& other) noexcept;
   Bytes& operator=(Bytes&& other) noexcept;
+  Bytes& operator=(nonstd::span<const uint8_t> data) noexcept;
+  Bytes& operator=(std::string_view data) noexcept;
 
   uint8_t operator[](size_t pos) const noexcept;
   uint8_t& operator[](size_t pos) noexcept;
@@ -106,13 +111,25 @@ inline Bytes::Bytes(const void* data, size_t size) noexcept
   std::memcpy(m_data.get(), data, size);
 }
 
+inline Bytes::Bytes(const void* first, const void* last) noexcept
+  : Bytes(first,
+          reinterpret_cast<const uint8_t*>(last)
+            - reinterpret_cast<const uint8_t*>(first))
+{
+}
+
 inline Bytes::Bytes(nonstd::span<const uint8_t> data) noexcept
   : Bytes(data.data(), data.size())
 {
 }
 
+inline Bytes::Bytes(std::string_view data) noexcept
+  : Bytes(data.data(), data.size())
+{
+}
+
 inline Bytes::Bytes(std::initializer_list<uint8_t> init) noexcept
-  : Bytes({init.begin(), init.end()})
+  : Bytes(init.begin(), init.end())
 {
 }
 
index 11c6927e75443ba8e3ecc0fd737783395920d0c0..c3a320c6fca2e29702b8a5c687e79f3212337309 100644 (file)
@@ -71,6 +71,18 @@ TEST_CASE("Basics")
     CHECK(bytes2[2] == 'c');
   }
 
+  SUBCASE("Construction from string_view")
+  {
+    std::string s("abc");
+    Bytes bytes2(s);
+
+    CHECK(bytes2.data() != nullptr);
+    REQUIRE(bytes2.size() == 3);
+    CHECK(bytes2[0] == 'a');
+    CHECK(bytes2[1] == 'b');
+    CHECK(bytes2[2] == 'c');
+  }
+
   SUBCASE("Copy construction")
   {
     const Bytes bytes2(bytes1);
@@ -138,6 +150,32 @@ TEST_CASE("Basics")
     CHECK(bytes2[2] == 'c');
   }
 
+  SUBCASE("Assignment from span")
+  {
+    std::vector<uint8_t> vector{'a', 'b', 'c'};
+    Bytes bytes2;
+    bytes2 = vector;
+
+    CHECK(bytes2.data() != nullptr);
+    REQUIRE(bytes2.size() == 3);
+    CHECK(bytes2[0] == 'a');
+    CHECK(bytes2[1] == 'b');
+    CHECK(bytes2[2] == 'c');
+  }
+
+  SUBCASE("Assignment from string_view")
+  {
+    std::string s = "abc";
+    Bytes bytes2;
+    bytes2 = s;
+
+    CHECK(bytes2.data() != nullptr);
+    REQUIRE(bytes2.size() == 3);
+    CHECK(bytes2[0] == 'a');
+    CHECK(bytes2[1] == 'b');
+    CHECK(bytes2[2] == 'c');
+  }
+
   SUBCASE("Assignment from initializer list")
   {
     Bytes bytes2;