summaryrefslogtreecommitdiff
path: root/src/string.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2021-07-20 19:53:06 +1000
committerMaxime Coste <mawww@kakoune.org>2021-07-20 22:30:41 +1000
commita4dd89f214e72005f551cd071d7642652c2922c5 (patch)
treebbbd8e27bce9ade970e1082ac389a830ca7f1ede /src/string.cc
parentc643cd446712a9f9db05081786b5bc0daf2a96d7 (diff)
Improve code-generation for Strings
Make String::Data use trivial copy of the short/long union to avoid unnecessary branching there, inline release() as it can be elided by the compiler on moved-from Strings.
Diffstat (limited to 'src/string.cc')
-rw-r--r--src/string.cc49
1 files changed, 16 insertions, 33 deletions
diff --git a/src/string.cc b/src/string.cc
index 37467451..fe763165 100644
--- a/src/string.cc
+++ b/src/string.cc
@@ -14,29 +14,18 @@ String::Data::Data(const char* data, size_t size, size_t capacity)
++capacity;
kak_assert(capacity < Long::max_capacity);
- l.ptr = Alloc{}.allocate(capacity+1);
- l.size = size;
- l.capacity = capacity;
+ u.l.ptr = Alloc{}.allocate(capacity+1);
+ u.l.size = size;
+ u.l.capacity = capacity;
if (data != nullptr)
- memcpy(l.ptr, data, size);
- l.ptr[size] = 0;
+ memcpy(u.l.ptr, data, size);
+ u.l.ptr[size] = 0;
}
else
set_short(data, size);
}
-String::Data::Data(Data&& other) noexcept
-{
- if (other.is_long())
- {
- l = other.l;
- other.set_empty();
- }
- else
- s = other.s;
-}
-
String::Data& String::Data::operator=(const Data& other)
{
if (&other == this)
@@ -59,11 +48,11 @@ String::Data& String::Data::operator=(Data&& other) noexcept
if (other.is_long())
{
- l = other.l;
+ u.l = other.u.l;
other.set_empty();
}
else
- s = other.s;
+ u.s = other.u.s;
return *this;
}
@@ -75,7 +64,7 @@ void String::Data::reserve(size_t new_capacity)
return;
if (is_long())
- new_capacity = std::max(l.capacity * 2, new_capacity);
+ new_capacity = std::max(u.l.capacity * 2, new_capacity);
if (new_capacity & 1)
++new_capacity;
@@ -85,12 +74,12 @@ void String::Data::reserve(size_t new_capacity)
if (copy)
{
memcpy(new_ptr, data(), size()+1);
- l.size = size();
+ u.l.size = size();
}
release();
- l.ptr = new_ptr;
- l.capacity = new_capacity;
+ u.l.ptr = new_ptr;
+ u.l.capacity = new_capacity;
}
template void String::Data::reserve<true>(size_t);
@@ -121,12 +110,6 @@ void String::Data::clear()
set_empty();
}
-void String::Data::release()
-{
- if (is_long() and l.capacity != 0)
- Alloc{}.deallocate(l.ptr, l.capacity+1);
-}
-
void String::resize(ByteCount size, char c)
{
const size_t target_size = (size_t)size;
@@ -146,17 +129,17 @@ void String::resize(ByteCount size, char c)
void String::Data::set_size(size_t size)
{
if (is_long())
- l.size = size;
+ u.l.size = size;
else
- s.size = (size << 1) | 1;
+ u.s.size = (size << 1) | 1;
}
void String::Data::set_short(const char* data, size_t size)
{
- s.size = (size << 1) | 1;
+ u.s.size = (size << 1) | 1;
if (data != nullptr)
- memcpy(s.string, data, size);
- s.string[size] = 0;
+ memcpy(u.s.string, data, size);
+ u.s.string[size] = 0;
}
const String String::ms_empty;