Utils: Remove code duplication in SmallString

It removes unwanted null termination too.

Change-Id: Iaea8699f7ccc387776b43e897fdd099764af2773
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2022-08-18 02:19:57 +02:00
parent 0ec7a3797d
commit 5a8d7c3d51

View File

@@ -97,15 +97,12 @@ public:
BasicSmallString(const char *string, size_type size, size_type capacity) BasicSmallString(const char *string, size_type size, size_type capacity)
{ {
if (Q_LIKELY(capacity <= shortStringCapacity())) { if (Q_LIKELY(capacity <= shortStringCapacity())) {
m_data.control = Internal::ControlBlock<Size>(size, false, false);
std::char_traits<char>::copy(m_data.shortString, string, size); std::char_traits<char>::copy(m_data.shortString, string, size);
m_data.shortString[size] = 0;
m_data.control.setShortStringSize(size);
m_data.control.setIsShortString(true);
m_data.control.setIsReadOnlyReference(false);
} else { } else {
m_data.reference.pointer = Memory::allocate(capacity); auto pointer = Memory::allocate(capacity);
std::char_traits<char>::copy(m_data.reference.pointer, string, size); std::char_traits<char>::copy(pointer, string, size);
initializeLongString(size, capacity); initializeLongString(pointer, size, capacity);
} }
} }
@@ -181,8 +178,7 @@ public:
BasicSmallString &operator=(const BasicSmallString &other) BasicSmallString &operator=(const BasicSmallString &other)
{ {
if (Q_LIKELY(this != &other)) { if (Q_LIKELY(this != &other)) {
if (Q_UNLIKELY(hasAllocatedMemory())) this->~BasicSmallString();
Memory::deallocate(m_data.reference.pointer);
if (Q_LIKELY(other.isShortString() || other.isReadOnlyReference())) if (Q_LIKELY(other.isShortString() || other.isReadOnlyReference()))
m_data = other.m_data; m_data = other.m_data;
@@ -202,8 +198,7 @@ public:
BasicSmallString &operator=(BasicSmallString &&other) noexcept BasicSmallString &operator=(BasicSmallString &&other) noexcept
{ {
if (Q_LIKELY(this != &other)) { if (Q_LIKELY(this != &other)) {
if (Q_UNLIKELY(hasAllocatedMemory())) this->~BasicSmallString();
Memory::deallocate(m_data.reference.pointer);
m_data = std::move(other.m_data); m_data = std::move(other.m_data);
other.m_data.reset(); other.m_data.reset();
@@ -276,17 +271,9 @@ public:
if (Q_UNLIKELY(hasAllocatedMemory())) { if (Q_UNLIKELY(hasAllocatedMemory())) {
m_data.reference.pointer = Memory::reallocate(m_data.reference.pointer, newCapacity); m_data.reference.pointer = Memory::reallocate(m_data.reference.pointer, newCapacity);
m_data.reference.capacity = newCapacity; m_data.reference.capacity = newCapacity;
} else if (newCapacity <= shortStringCapacity()) {
new (this) BasicSmallString{m_data.reference.pointer, m_data.reference.size};
} else { } else {
const size_type oldSize = size(); auto oldSize = size();
newCapacity = std::max(newCapacity, oldSize); new (this) BasicSmallString{data(), oldSize, std::max(newCapacity, oldSize)};
const char *oldData = data();
char *newData = Memory::allocate(newCapacity);
std::char_traits<char>::copy(newData, oldData, oldSize);
m_data.reference.pointer = newData;
initializeLongString(oldSize, newCapacity);
} }
} }
} }
@@ -790,14 +777,12 @@ private:
} }
} }
constexpr void initializeLongString(size_type size, size_type capacity) constexpr void initializeLongString(char *pointer, size_type size, size_type capacity)
{ {
m_data.reference.pointer[size] = 0; m_data.control = Internal::ControlBlock<Size>(0, false, true);
m_data.reference.pointer = pointer;
m_data.reference.size = size; m_data.reference.size = size;
m_data.reference.capacity = capacity; m_data.reference.capacity = capacity;
m_data.control.setShortStringSize(0);
m_data.control.setIsReference(true);
m_data.control.setIsReadOnlyReference(false);
} }
char &at(size_type index) char &at(size_type index)