From e17ab4ffe5b675b0163368cd893d2e703c874675 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Mon, 20 May 2024 17:52:04 +0200 Subject: Use string_view for Linda names --- src/linda.cpp | 55 +++++++++++++++++++++++++++++----------------------- src/linda.h | 14 +++++-------- src/lindafactory.cpp | 2 +- 3 files changed, 37 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/linda.cpp b/src/linda.cpp index 48da1cf..1916629 100644 --- a/src/linda.cpp +++ b/src/linda.cpp @@ -79,10 +79,11 @@ template { Linda* const _linda{ ToLinda(L_, idx_) }; if (_linda != nullptr) { + std::string_view const _lindaName{ _linda->getName() }; char _text[128]; int _len; - if (_linda->getName()) - _len = sprintf(_text, "Linda: %.*s", (int) sizeof(_text) - 8, _linda->getName()); + if (!_lindaName.empty()) + _len = sprintf(_text, "Linda: %.*s", (int) sizeof(_text) - 8, _lindaName.data()); else _len = sprintf(_text, "Linda: %p", _linda); lua_pushlstring(L_, _text, _len); @@ -113,37 +114,37 @@ template // have to cast to unsigned long to avoid compilation warnings about loss of data when converting pointer-to-integer static constexpr uintptr_t kPointerMagicShift{ 3 }; -Linda::Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_) +Linda::Linda(Universe* U_, LindaGroup group_, std::string_view const& name_) : DeepPrelude{ LindaFactory::Instance } , U{ U_ } , keeperIndex{ (group_ ? group_ : static_cast(std::bit_cast(this) >> kPointerMagicShift)) % U_->keepers->nb_keepers } { - setName(name_, len_); + setName(name_); } // ################################################################################################# Linda::~Linda() { - if (std::holds_alternative(nameVariant)) { - AllocatedName& _name = std::get(nameVariant); - U->internalAllocator.free(_name.name, _name.len); + if (std::holds_alternative(nameVariant)) { + std::string_view& _name = std::get(nameVariant); + U->internalAllocator.free(const_cast(_name.data()), _name.size()); } } // ################################################################################################# -char const* Linda::getName() const +std::string_view Linda::getName() const { - if (std::holds_alternative(nameVariant)) { - AllocatedName const& _name = std::get(nameVariant); - return _name.name; + if (std::holds_alternative(nameVariant)) { + std::string_view const& _name = std::get(nameVariant); + return _name; } if (std::holds_alternative(nameVariant)) { char const* const _name{ std::get(nameVariant).data() }; - return _name; + return std::string_view{ _name, strlen(_name) }; } - return nullptr; + return std::string_view{}; } // ################################################################################################# @@ -182,22 +183,28 @@ int Linda::ProtectedCall(lua_State* L_, lua_CFunction f_) // ################################################################################################# -void Linda::setName(char const* name_, size_t len_) +void Linda::setName(std::string_view const& name_) { // keep default - if (!name_ || len_ == 0) { + if (name_.empty()) { return; } - ++len_; // don't forget terminating 0 - if (len_ < kEmbeddedNameLength) { - nameVariant.emplace(); - char* const _name{ std::get(nameVariant).data() }; - memcpy(_name, name_, len_); + size_t const _lenWithTZ{ name_.size() + 1 }; // don't forget terminating 0 + if (_lenWithTZ < kEmbeddedNameLength) { + // grab our internal buffer + EmbeddedName& _name = nameVariant.emplace(); + // copy the string in it + memcpy(_name.data(), name_.data(), name_.size()); + // don't forget terminating 0 + _name[_lenWithTZ] = 0; } else { - AllocatedName& _name = std::get(nameVariant); - _name.name = static_cast(U->internalAllocator.alloc(len_)); - _name.len = len_; - memcpy(_name.name, name_, len_); + // allocate an external buffer + char* const _nameBuffer{ static_cast(U->internalAllocator.alloc(_lenWithTZ)) }; + // copy the string in it + memcpy(_nameBuffer, name_.data(), name_.size()); + // don't forget terminating 0 + _nameBuffer[_lenWithTZ] = 0; + nameVariant.emplace(_nameBuffer, name_.size()); } } diff --git a/src/linda.h b/src/linda.h index 4943197..611008e 100644 --- a/src/linda.h +++ b/src/linda.h @@ -7,6 +7,7 @@ #include #include +#include #include struct Keeper; @@ -26,13 +27,8 @@ class Linda private: static constexpr size_t kEmbeddedNameLength = 24; using EmbeddedName = std::array; - struct AllocatedName - { - size_t len{ 0 }; - char* name{ nullptr }; - }; // depending on the name length, it is either embedded inside the Linda, or allocated separately - std::variant nameVariant; + std::variant nameVariant; public: std::condition_variable readHappened; @@ -51,7 +47,7 @@ class Linda static void operator delete(void* p_) { static_cast(p_)->U->internalAllocator.free(p_, sizeof(Linda)); } ~Linda(); - Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_); + Linda(Universe* U_, LindaGroup group_, std::string_view const& name_); Linda() = delete; // non-copyable, non-movable Linda(Linda const&) = delete; @@ -60,11 +56,11 @@ class Linda Linda& operator=(Linda const&&) = delete; private: - void setName(char const* name_, size_t len_); + void setName(std::string_view const& name_); public: [[nodiscard]] Keeper* acquireKeeper() const; - [[nodiscard]] char const* getName() const; + [[nodiscard]] std::string_view getName() const; void releaseKeeper(Keeper* keeper_) const; [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_); [[nodiscard]] Keeper* whichKeeper() const { return U->keepers->nb_keepers ? &U->keepers->keeper_array[keeperIndex] : nullptr; } diff --git a/src/lindafactory.cpp b/src/lindafactory.cpp index 015baf4..890cc96 100644 --- a/src/lindafactory.cpp +++ b/src/lindafactory.cpp @@ -127,6 +127,6 @@ DeepPrelude* LindaFactory::newDeepObjectInternal(lua_State* L_) const // The deep data is allocated separately of Lua stack; we might no longer be around when last reference to it is being released. // One can use any memory allocation scheme. Just don't use L's allocF because we don't know which state will get the honor of GCing the linda Universe* const _U{ universe_get(L_) }; - Linda* const _linda{ new (_U) Linda{ _U, _linda_group, _linda_name.data(), _linda_name.size() } }; + Linda* const _linda{ new (_U) Linda{ _U, _linda_group, _linda_name } }; return _linda; } -- cgit v1.2.3-55-g6feb