aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/zencore/include')
-rw-r--r--src/zencore/include/zencore/string.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/zencore/include/zencore/string.h b/src/zencore/include/zencore/string.h
index b4926070c..a1c7a3914 100644
--- a/src/zencore/include/zencore/string.h
+++ b/src/zencore/include/zencore/string.h
@@ -1349,6 +1349,70 @@ std::string HideSensitiveString(std::string_view String);
//////////////////////////////////////////////////////////////////////////
+/// Owns a heap-allocated, null-terminated string buffer.
+/// Lightweight alternative to std::string when only immutable
+/// storage and string_view access are needed.
+///
+/// The buffer layout is [length-prefix][chars...][NUL]. The first
+/// byte stores the string length for strings shorter than 255 bytes,
+/// avoiding strlen() on every access. A sentinel value of 0xFF
+/// indicates a longer string; Size() then returns 255 + strlen()
+/// starting at the 256th character, skipping the known prefix.
+class CompactString
+{
+public:
+ CompactString() = default;
+
+ explicit CompactString(std::string_view Str) : m_Data(new char[1 + Str.size() + 1])
+ {
+ m_Data[0] = static_cast<char>(Str.size() < LengthFallbackSentinel ? Str.size() : LengthFallbackSentinel);
+ memcpy(m_Data + 1, Str.data(), Str.size());
+ m_Data[1 + Str.size()] = '\0';
+ }
+
+ ~CompactString() { delete[] m_Data; }
+
+ CompactString(const CompactString&) = delete;
+ CompactString& operator=(const CompactString&) = delete;
+
+ CompactString(CompactString&& Other) noexcept : m_Data(Other.m_Data) { Other.m_Data = nullptr; }
+
+ CompactString& operator=(CompactString&& Other) noexcept
+ {
+ if (this != &Other)
+ {
+ delete[] m_Data;
+ m_Data = Other.m_Data;
+ Other.m_Data = nullptr;
+ }
+ return *this;
+ }
+
+ const char* c_str() const { return m_Data ? m_Data + 1 : ""; }
+
+ size_t Size() const
+ {
+ if (!m_Data)
+ {
+ return 0;
+ }
+ uint8_t Prefix = static_cast<uint8_t>(m_Data[0]);
+ return Prefix < LengthFallbackSentinel ? Prefix : LengthFallbackSentinel + strlen(m_Data + 1 + LengthFallbackSentinel);
+ }
+
+ std::string_view ToView() const { return {c_str(), Size()}; }
+ bool IsEmpty() const { return m_Data == nullptr || m_Data[1] == '\0'; }
+
+ operator std::string_view() const { return ToView(); }
+
+private:
+ static constexpr uint8_t LengthFallbackSentinel = 0xFF;
+
+ char* m_Data = nullptr;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
void string_forcelink(); // internal
} // namespace zen