mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-17 22:25:37 +00:00
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)
|
static bool StringDataIsSharable(const String::StringData* pStringData)
|
||||||
{
|
{
|
||||||
return pStringData->ReferenceCount != -1;
|
return pStringData->ReadOnly || pStringData->ReferenceCount != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool StringDataIsShared(const String::StringData* pStringData)
|
static bool StringDataIsShared(const String::StringData* pStringData)
|
||||||
|
@ -145,6 +145,7 @@ String::String(const String& copyString)
|
||||||
else if (StringDataIsSharable(copyString.m_pStringData))
|
else if (StringDataIsSharable(copyString.m_pStringData))
|
||||||
{
|
{
|
||||||
m_pStringData = copyString.m_pStringData;
|
m_pStringData = copyString.m_pStringData;
|
||||||
|
if (!m_pStringData->ReadOnly)
|
||||||
StringDataAddRef(m_pStringData);
|
StringDataAddRef(m_pStringData);
|
||||||
}
|
}
|
||||||
// create a clone for ourselves
|
// create a clone for ourselves
|
||||||
|
@ -525,6 +526,7 @@ void String::Assign(const String& copyString)
|
||||||
else if (StringDataIsSharable(copyString.m_pStringData))
|
else if (StringDataIsSharable(copyString.m_pStringData))
|
||||||
{
|
{
|
||||||
m_pStringData = copyString.m_pStringData;
|
m_pStringData = copyString.m_pStringData;
|
||||||
|
if (!m_pStringData->ReadOnly)
|
||||||
StringDataAddRef(m_pStringData);
|
StringDataAddRef(m_pStringData);
|
||||||
}
|
}
|
||||||
// create a clone for ourselves
|
// create a clone for ourselves
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <atomic>
|
#include <algorithm>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
@ -29,7 +29,7 @@ public:
|
||||||
// Reference count of this data object. If set to -1,
|
// Reference count of this data object. If set to -1,
|
||||||
// it is considered noncopyable and any copies of the string
|
// it is considered noncopyable and any copies of the string
|
||||||
// will always create their own copy.
|
// will always create their own copy.
|
||||||
std::atomic<s32> ReferenceCount;
|
s32 ReferenceCount;
|
||||||
|
|
||||||
// Whether the memory pointed to by pBuffer is writable.
|
// Whether the memory pointed to by pBuffer is writable.
|
||||||
bool ReadOnly;
|
bool ReadOnly;
|
||||||
|
@ -50,6 +50,9 @@ public:
|
||||||
// Move constructor, take reference from other string.
|
// Move constructor, take reference from other string.
|
||||||
String(String&& moveString);
|
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.
|
// Destructor. Child classes may not have any destructors, as this is not virtual.
|
||||||
~String();
|
~String();
|
||||||
|
|
||||||
|
@ -251,10 +254,6 @@ public:
|
||||||
bool operator>(const char* compString) const { return (NumericCompare(compString) > 0); }
|
bool operator>(const char* compString) const { return (NumericCompare(compString) > 0); }
|
||||||
|
|
||||||
protected:
|
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.
|
// Internal append function.
|
||||||
void InternalPrepend(const char* pString, u32 Length);
|
void InternalPrepend(const char* pString, u32 Length);
|
||||||
void InternalAppend(const char* pString, u32 Length);
|
void InternalAppend(const char* pString, u32 Length);
|
||||||
|
@ -267,21 +266,14 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
// static string, stored in .rodata
|
// static string, stored in .rodata
|
||||||
class StaticString : public String
|
#define StaticString(Text) \
|
||||||
{
|
[]() noexcept -> String { \
|
||||||
public:
|
static constexpr u32 buffer_size = sizeof(Text); \
|
||||||
StaticString(const char* Text)
|
static constexpr u32 length = buffer_size - 1; \
|
||||||
{
|
static constexpr String::StringData data{const_cast<char*>(Text), length, buffer_size, static_cast<s32>(-1), \
|
||||||
m_sStringData.pBuffer = const_cast<char*>(Text);
|
true}; \
|
||||||
m_sStringData.StringLength = static_cast<u32>(std::strlen(Text));
|
return String(const_cast<String::StringData*>(&data)); \
|
||||||
m_sStringData.BufferSize = m_sStringData.StringLength + 1;
|
}()
|
||||||
m_sStringData.ReadOnly = true;
|
|
||||||
m_sStringData.ReferenceCount = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
StringData m_sStringData;
|
|
||||||
};
|
|
||||||
|
|
||||||
// stack-allocated string
|
// stack-allocated string
|
||||||
template<u32 L>
|
template<u32 L>
|
||||||
|
|
Loading…
Reference in a new issue