diff --git a/src/command_manager.cc b/src/command_manager.cc index 42e7f802..f777eeda 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -121,11 +121,11 @@ QuotedResult parse_quoted_balanced(Reader& reader, char opening_delimiter, { auto content = reader.substr_from(start); ++reader.pos; - return {content.str(), true}; + return {String{String::NoCopy{}, content}, true}; } ++reader.pos; } - return {reader.substr_from(start).str(), false}; + return {String{String::NoCopy{}, reader.substr_from(start)}, false}; } String parse_unquoted(Reader& reader) diff --git a/src/string.cc b/src/string.cc index 6ff89450..d44963ba 100644 --- a/src/string.cc +++ b/src/string.cc @@ -6,6 +6,13 @@ namespace Kakoune { +String::Data::Data(String::NoCopy, const char* data, size_t size) +{ + l.ptr = const_cast(data); + l.size = size; + l.capacity = 0; +} + String::Data::Data(const char* data, size_t size, size_t capacity) { if (capacity > Short::capacity) @@ -71,7 +78,7 @@ String::Data& String::Data::operator=(Data&& other) noexcept template void String::Data::reserve(size_t new_capacity) { - if (new_capacity <= capacity()) + if (capacity() != 0 and new_capacity <= capacity()) return; if (is_long()) @@ -123,7 +130,7 @@ void String::Data::clear() void String::Data::release() { - if (is_long()) + if (is_long() and l.capacity != 0) Alloc{}.deallocate(l.ptr, l.capacity+1); } diff --git a/src/string.hh b/src/string.hh index ae41642c..e69be344 100644 --- a/src/string.hh +++ b/src/string.hh @@ -121,6 +121,9 @@ public: explicit String(StringView str); + struct NoCopy{}; + String(NoCopy, StringView str); + [[gnu::always_inline]] char* data() { return m_data.data(); } @@ -175,6 +178,7 @@ public: } s; Data() { set_empty(); } + Data(NoCopy, const char* data, size_t size); Data(const char* data, size_t size, size_t capacity); Data(const char* data, size_t size) : Data(data, size, size) {} Data(const Data& other) : Data{other.data(), other.size()} {} @@ -257,6 +261,7 @@ template<> struct HashCompatible : std::true_type {}; template<> struct HashCompatible : std::true_type {}; inline String::String(StringView str) : String{str.begin(), str.length()} {} +inline String::String(NoCopy, StringView str) : m_data{NoCopy{}, str.begin(), (size_t)str.length()} {} template inline StringView StringOps::substr(ByteCount from, ByteCount length) const