From 88c201167d1d50a1c19480d0f88e28f36c6adcdc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 16 Jan 2026 20:47:54 -0500 Subject: [PATCH] xo-expression2: DUniqueSring: fix copy during hypothetical GC --- .../include/xo/expression2/DUniqueString.hpp | 8 +++++++- .../src/expression2/DUniqueString.cpp | 18 ++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/xo-expression2/include/xo/expression2/DUniqueString.hpp b/xo-expression2/include/xo/expression2/DUniqueString.hpp index 46fdfa1e..08fcde86 100644 --- a/xo-expression2/include/xo/expression2/DUniqueString.hpp +++ b/xo-expression2/include/xo/expression2/DUniqueString.hpp @@ -59,6 +59,10 @@ namespace xo { /** @defgroup duniquestring-methods methods **/ ///@{ + /** Available storage for this instance. + * For completeness' sake since uniquestring not modifiable + **/ + size_type capacity() const noexcept { return _text()->capacity(); } size_type size() const noexcept { return _text()->size(); } const char * chars() const noexcept { return _text()->chars(); } @@ -74,6 +78,8 @@ namespace xo { std::size_t hash() const noexcept { return _text()->hash(); } operator std::string_view() const noexcept { return std::string_view(*_text()); } + /** not assignable **/ + DUniqueString & operator=(const DUniqueString &) = delete; ///@} /** @defgroup duniquestring-printable-methods printable facet methods **/ @@ -105,7 +111,7 @@ namespace xo { /** DString containing actual string content immediately follows DUniqueString * in memory; part of same alloc **/ - const DString * _text() const noexcept; + DString * _text() const noexcept; //explicit DUniqueString(const DString * text) : text_{text} {} diff --git a/xo-expression2/src/expression2/DUniqueString.cpp b/xo-expression2/src/expression2/DUniqueString.cpp index d0a4b0a0..c0fa26db 100644 --- a/xo-expression2/src/expression2/DUniqueString.cpp +++ b/xo-expression2/src/expression2/DUniqueString.cpp @@ -6,13 +6,14 @@ #include "DUniqueString.hpp" #include #include +#include namespace xo { using xo::mm::padding; using xo::facet::typeseq; namespace scm { - const DString * + DString * DUniqueString::_text() const noexcept { // location of paired DString is chosen @@ -30,7 +31,7 @@ namespace xo { size_t offset = padding::with_padding(sizeof(*this)); assert(offset > 0); - return (const DString *)(((std::byte *)this) + offset); + return (DString *)(((std::byte *)this) + offset); } bool @@ -84,8 +85,17 @@ namespace xo { DUniqueString * copy = (DUniqueString *)mm.alloc_copy((std::byte *)this); - if (copy) - *copy = *this; + if (copy) { + // Copy assignment not implemented in general + // *copy = *this; + // in this case *copy already has the same size as *this + + assert(size() <= capacity()); + + strncpy(copy->_text()->data(), + this->_text()->chars(), + this->size()); + } return copy; }