From 24e41beab4861b85ead9062498e36f63bef69a7b Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Sat, 25 Oct 2025 16:26:28 +0200 Subject: [PATCH] enhance: Add more util::Bytes constructor and operator= variants --- src/ccache/util/bytes.cpp | 34 ++++++++++++++++++++++++++------ src/ccache/util/bytes.hpp | 19 +++++++++++++++++- unittest/test_util_bytes.cpp | 38 ++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 7 deletions(-) diff --git a/src/ccache/util/bytes.cpp b/src/ccache/util/bytes.cpp index b3e01fee..4856d184 100644 --- a/src/ccache/util/bytes.cpp +++ b/src/ccache/util/bytes.cpp @@ -22,6 +22,19 @@ 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(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(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 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 { diff --git a/src/ccache/util/bytes.hpp b/src/ccache/util/bytes.hpp index c44da78e..d7545e2a 100644 --- a/src/ccache/util/bytes.hpp +++ b/src/ccache/util/bytes.hpp @@ -24,6 +24,7 @@ #include #include #include +#include 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 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 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(last) + - reinterpret_cast(first)) +{ +} + inline Bytes::Bytes(nonstd::span 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 init) noexcept - : Bytes({init.begin(), init.end()}) + : Bytes(init.begin(), init.end()) { } diff --git a/unittest/test_util_bytes.cpp b/unittest/test_util_bytes.cpp index 11c6927e..c3a320c6 100644 --- a/unittest/test_util_bytes.cpp +++ b/unittest/test_util_bytes.cpp @@ -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 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; -- 2.47.3