Common/String: Don't copy StaticStrings when not writing
This commit is contained in:
parent
4fe57e64d7
commit
86094b8080
|
@ -124,7 +124,7 @@ static String::StringData* StringDataReallocate(String::StringData* pStringData,
|
|||
|
||||
static bool StringDataIsSharable(const String::StringData* pStringData)
|
||||
{
|
||||
return pStringData->ReferenceCount != -1;
|
||||
return pStringData->ReadOnly || pStringData->ReferenceCount != -1;
|
||||
}
|
||||
|
||||
static bool StringDataIsShared(const String::StringData* pStringData)
|
||||
|
@ -145,7 +145,8 @@ String::String(const String& copyString)
|
|||
else if (StringDataIsSharable(copyString.m_pStringData))
|
||||
{
|
||||
m_pStringData = copyString.m_pStringData;
|
||||
StringDataAddRef(m_pStringData);
|
||||
if (!m_pStringData->ReadOnly)
|
||||
StringDataAddRef(m_pStringData);
|
||||
}
|
||||
// create a clone for ourselves
|
||||
else
|
||||
|
@ -525,7 +526,8 @@ void String::Assign(const String& copyString)
|
|||
else if (StringDataIsSharable(copyString.m_pStringData))
|
||||
{
|
||||
m_pStringData = copyString.m_pStringData;
|
||||
StringDataAddRef(m_pStringData);
|
||||
if (!m_pStringData->ReadOnly)
|
||||
StringDataAddRef(m_pStringData);
|
||||
}
|
||||
// create a clone for ourselves
|
||||
else
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include "types.h"
|
||||
#include <atomic>
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
@ -29,7 +29,7 @@ public:
|
|||
// Reference count of this data object. If set to -1,
|
||||
// it is considered noncopyable and any copies of the string
|
||||
// will always create their own copy.
|
||||
std::atomic<s32> ReferenceCount;
|
||||
s32 ReferenceCount;
|
||||
|
||||
// Whether the memory pointed to by pBuffer is writable.
|
||||
bool ReadOnly;
|
||||
|
@ -50,6 +50,9 @@ public:
|
|||
// Move constructor, take reference from other string.
|
||||
String(String&& moveString);
|
||||
|
||||
// Construct a string from a data object, does not increment the reference count on the string data, use carefully.
|
||||
explicit String(StringData* pStringData) : m_pStringData(pStringData) {}
|
||||
|
||||
// Destructor. Child classes may not have any destructors, as this is not virtual.
|
||||
~String();
|
||||
|
||||
|
@ -251,10 +254,6 @@ public:
|
|||
bool operator>(const char* compString) const { return (NumericCompare(compString) > 0); }
|
||||
|
||||
protected:
|
||||
// Hidden constructor for creating string child classes.
|
||||
// It does not increment the reference count on the string data, therefore dangerous to be public.
|
||||
String(StringData* pStringData) : m_pStringData(pStringData) {}
|
||||
|
||||
// Internal append function.
|
||||
void InternalPrepend(const char* pString, u32 Length);
|
||||
void InternalAppend(const char* pString, u32 Length);
|
||||
|
@ -267,21 +266,14 @@ protected:
|
|||
};
|
||||
|
||||
// static string, stored in .rodata
|
||||
class StaticString : public String
|
||||
{
|
||||
public:
|
||||
StaticString(const char* Text)
|
||||
{
|
||||
m_sStringData.pBuffer = const_cast<char*>(Text);
|
||||
m_sStringData.StringLength = static_cast<u32>(std::strlen(Text));
|
||||
m_sStringData.BufferSize = m_sStringData.StringLength + 1;
|
||||
m_sStringData.ReadOnly = true;
|
||||
m_sStringData.ReferenceCount = -1;
|
||||
}
|
||||
|
||||
private:
|
||||
StringData m_sStringData;
|
||||
};
|
||||
#define StaticString(Text) \
|
||||
[]() noexcept -> String { \
|
||||
static constexpr u32 buffer_size = sizeof(Text); \
|
||||
static constexpr u32 length = buffer_size - 1; \
|
||||
static constexpr String::StringData data{const_cast<char*>(Text), length, buffer_size, static_cast<s32>(-1), \
|
||||
true}; \
|
||||
return String(const_cast<String::StringData*>(&data)); \
|
||||
}()
|
||||
|
||||
// stack-allocated string
|
||||
template<u32 L>
|
||||
|
|
Loading…
Reference in New Issue