Make String able to reference external data without copying
Sometimes we really need to have a String instead of a StringView, but some of those strings might not need to own their data. Make it possible to explicitely construct a String that does not own the underlying buffer. Use it when parsing balanced strings.
This commit is contained in:
parent
c2be661785
commit
56611604b2
|
@ -121,11 +121,11 @@ QuotedResult parse_quoted_balanced(Reader& reader, char opening_delimiter,
|
||||||
{
|
{
|
||||||
auto content = reader.substr_from(start);
|
auto content = reader.substr_from(start);
|
||||||
++reader.pos;
|
++reader.pos;
|
||||||
return {content.str(), true};
|
return {String{String::NoCopy{}, content}, true};
|
||||||
}
|
}
|
||||||
++reader.pos;
|
++reader.pos;
|
||||||
}
|
}
|
||||||
return {reader.substr_from(start).str(), false};
|
return {String{String::NoCopy{}, reader.substr_from(start)}, false};
|
||||||
}
|
}
|
||||||
|
|
||||||
String parse_unquoted(Reader& reader)
|
String parse_unquoted(Reader& reader)
|
||||||
|
|
|
@ -6,6 +6,13 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
|
String::Data::Data(String::NoCopy, const char* data, size_t size)
|
||||||
|
{
|
||||||
|
l.ptr = const_cast<char*>(data);
|
||||||
|
l.size = size;
|
||||||
|
l.capacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
String::Data::Data(const char* data, size_t size, size_t capacity)
|
String::Data::Data(const char* data, size_t size, size_t capacity)
|
||||||
{
|
{
|
||||||
if (capacity > Short::capacity)
|
if (capacity > Short::capacity)
|
||||||
|
@ -71,7 +78,7 @@ String::Data& String::Data::operator=(Data&& other) noexcept
|
||||||
template<bool copy>
|
template<bool copy>
|
||||||
void String::Data::reserve(size_t new_capacity)
|
void String::Data::reserve(size_t new_capacity)
|
||||||
{
|
{
|
||||||
if (new_capacity <= capacity())
|
if (capacity() != 0 and new_capacity <= capacity())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (is_long())
|
if (is_long())
|
||||||
|
@ -123,7 +130,7 @@ void String::Data::clear()
|
||||||
|
|
||||||
void String::Data::release()
|
void String::Data::release()
|
||||||
{
|
{
|
||||||
if (is_long())
|
if (is_long() and l.capacity != 0)
|
||||||
Alloc{}.deallocate(l.ptr, l.capacity+1);
|
Alloc{}.deallocate(l.ptr, l.capacity+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,9 @@ public:
|
||||||
|
|
||||||
explicit String(StringView str);
|
explicit String(StringView str);
|
||||||
|
|
||||||
|
struct NoCopy{};
|
||||||
|
String(NoCopy, StringView str);
|
||||||
|
|
||||||
[[gnu::always_inline]]
|
[[gnu::always_inline]]
|
||||||
char* data() { return m_data.data(); }
|
char* data() { return m_data.data(); }
|
||||||
|
|
||||||
|
@ -175,6 +178,7 @@ public:
|
||||||
} s;
|
} s;
|
||||||
|
|
||||||
Data() { set_empty(); }
|
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, size_t capacity);
|
||||||
Data(const char* data, size_t size) : Data(data, size, size) {}
|
Data(const char* data, size_t size) : Data(data, size, size) {}
|
||||||
Data(const Data& other) : Data{other.data(), other.size()} {}
|
Data(const Data& other) : Data{other.data(), other.size()} {}
|
||||||
|
@ -257,6 +261,7 @@ template<> struct HashCompatible<String, StringView> : std::true_type {};
|
||||||
template<> struct HashCompatible<StringView, String> : std::true_type {};
|
template<> struct HashCompatible<StringView, String> : std::true_type {};
|
||||||
|
|
||||||
inline String::String(StringView str) : String{str.begin(), str.length()} {}
|
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<typename Type, typename CharType>
|
template<typename Type, typename CharType>
|
||||||
inline StringView StringOps<Type, CharType>::substr(ByteCount from, ByteCount length) const
|
inline StringView StringOps<Type, CharType>::substr(ByteCount from, ByteCount length) const
|
||||||
|
|
Loading…
Reference in New Issue
Block a user