You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Headers are updated to contain any missing #includes needed to compile and #includes are sorted. Nothing is removed. #ushell-cherrypick of 21064294 by bryan.sefcik #jira #preflight 62d5c2111062f2e63015e598 #ROBOMERGE-OWNER: bryan.sefcik #ROBOMERGE-AUTHOR: bryan.sefcik #ROBOMERGE-SOURCE: CL 21155249 via CL 21158121 via CL 21161259 #ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v972-20964824) [CL 21182053 by bryan sefcik in ue5-main branch]
192 lines
5.3 KiB
C++
192 lines
5.3 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Containers/StringView.h"
|
|
#include "CoreTypes.h"
|
|
#include "DerivedDataSharedStringFwd.h"
|
|
#include "HAL/MemoryBase.h"
|
|
#include "HAL/PlatformCrt.h"
|
|
#include "HAL/UnrealMemory.h"
|
|
#include "Misc/CString.h"
|
|
|
|
#include <atomic>
|
|
|
|
#define UE_API DERIVEDDATACACHE_API
|
|
|
|
class FCbFieldView;
|
|
class FCbWriter;
|
|
|
|
namespace UE::DerivedData
|
|
{
|
|
|
|
/**
|
|
* A reference to an immutable, shared, reference-counted string.
|
|
*
|
|
* Prefer TStringView when there is a clear single point of ownership with a longer lifetime than
|
|
* the references to the string. This type is meant for cases where a shared string does not have
|
|
* an obvious owner or where the lifetime is not easy to manage.
|
|
*
|
|
* The string is stored as a pointer to the start of the null-terminated string which is preceded
|
|
* by a 4-byte reference count and a 4-byte size.
|
|
*/
|
|
template <typename CharType>
|
|
class TSharedString
|
|
{
|
|
public:
|
|
TSharedString() = default;
|
|
TSharedString(TSharedString&& String);
|
|
TSharedString(const TSharedString& String);
|
|
TSharedString& operator=(TSharedString&& String);
|
|
TSharedString& operator=(const TSharedString& String);
|
|
|
|
TSharedString(TStringView<CharType> String);
|
|
TSharedString& operator=(TStringView<CharType> String);
|
|
|
|
~TSharedString() { Reset(); }
|
|
|
|
inline void Reset() { Release(Chars); Chars = nullptr; }
|
|
|
|
[[nodiscard]] inline bool IsEmpty() const { return !Chars; }
|
|
[[nodiscard]] inline int32 Len() const { return Chars ? reinterpret_cast<const int32*>(Chars)[-1] : 0; }
|
|
[[nodiscard]] inline const CharType* operator*() const { return Chars ? Chars : &NullChar; }
|
|
|
|
static const TSharedString Empty;
|
|
|
|
private:
|
|
static inline void AddRef(CharType* Chars);
|
|
static inline void Release(CharType* Chars);
|
|
|
|
CharType* Chars = nullptr;
|
|
|
|
static constexpr inline CharType NullChar{};
|
|
};
|
|
|
|
template <typename CharType>
|
|
inline const TSharedString<CharType> TSharedString<CharType>::Empty;
|
|
|
|
template <typename CharType>
|
|
constexpr inline const CharType* GetData(const TSharedString<CharType> String)
|
|
{
|
|
return *String;
|
|
}
|
|
|
|
template <typename CharType>
|
|
constexpr inline auto GetNum(const TSharedString<CharType> String)
|
|
{
|
|
return String.Len();
|
|
}
|
|
|
|
template <typename CharType>
|
|
inline TSharedString<CharType>::TSharedString(TSharedString&& String)
|
|
: Chars(String.Chars)
|
|
{
|
|
String.Chars = nullptr;
|
|
}
|
|
|
|
template <typename CharType>
|
|
TSharedString<CharType>::TSharedString(const TSharedString& String)
|
|
: Chars(String.Chars)
|
|
{
|
|
AddRef(Chars);
|
|
}
|
|
|
|
template <typename CharType>
|
|
TSharedString<CharType>& TSharedString<CharType>::operator=(TSharedString&& String)
|
|
{
|
|
if (this != &String)
|
|
{
|
|
Release(Chars);
|
|
Chars = String.Chars;
|
|
String.Chars = nullptr;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template <typename CharType>
|
|
TSharedString<CharType>& TSharedString<CharType>::operator=(const TSharedString& String)
|
|
{
|
|
CharType* OldChars = Chars;
|
|
CharType* NewChars = String.Chars;
|
|
AddRef(NewChars);
|
|
Release(OldChars);
|
|
Chars = NewChars;
|
|
return *this;
|
|
}
|
|
|
|
template <typename CharType>
|
|
TSharedString<CharType>::TSharedString(const TStringView<CharType> String)
|
|
{
|
|
if (const int32 Length = String.Len())
|
|
{
|
|
static_assert(alignof(int32) <= MIN_ALIGNMENT);
|
|
static_assert(alignof(int32) >= alignof(CharType));
|
|
static_assert(sizeof(int32) == sizeof(std::atomic<int32>));
|
|
const SIZE_T Size = sizeof(int32) + sizeof(int32) + sizeof(CharType) + sizeof(CharType) * Length;
|
|
int32* const Header = static_cast<int32*>(FMemory::Malloc(Size));
|
|
new(&Header[0]) std::atomic<int32>(1); // Ref Count
|
|
new(&Header[1]) int32(Length);
|
|
Chars = reinterpret_cast<CharType*>(&Header[2]);
|
|
String.CopyString(Chars, Length);
|
|
Chars[Length] = CharType(0);
|
|
}
|
|
}
|
|
|
|
template <typename CharType>
|
|
TSharedString<CharType>& TSharedString<CharType>::operator=(const TStringView<CharType> String)
|
|
{
|
|
return *this = TSharedString(String);
|
|
}
|
|
|
|
template <typename CharType>
|
|
void TSharedString<CharType>::AddRef(CharType* const MaybeNullChars)
|
|
{
|
|
if (MaybeNullChars)
|
|
{
|
|
static_assert(sizeof(int32) == sizeof(std::atomic<int32>));
|
|
int32* const Header = reinterpret_cast<int32*>(MaybeNullChars) - 2;
|
|
std::atomic<int32>& RefCount = reinterpret_cast<std::atomic<int32>&>(Header[0]);
|
|
RefCount.fetch_add(1, std::memory_order_relaxed);
|
|
}
|
|
}
|
|
|
|
template <typename CharType>
|
|
void TSharedString<CharType>::Release(CharType* const MaybeNullChars)
|
|
{
|
|
if (MaybeNullChars)
|
|
{
|
|
static_assert(sizeof(int32) == sizeof(std::atomic<int32>));
|
|
int32* const Header = reinterpret_cast<int32*>(MaybeNullChars) - 2;
|
|
std::atomic<int32>& RefCount = reinterpret_cast<std::atomic<int32>&>(Header[0]);
|
|
if (RefCount.fetch_sub(1, std::memory_order_relaxed) == 1)
|
|
{
|
|
FMemory::Free(Header);
|
|
}
|
|
}
|
|
}
|
|
|
|
template <typename CharType>
|
|
inline uint32 GetTypeHash(const TSharedString<CharType>& String)
|
|
{
|
|
return GetTypeHash(MakeStringView(String));
|
|
}
|
|
|
|
template <typename CharType>
|
|
inline bool operator==(const TSharedString<CharType>& Lhs, const TSharedString<CharType>& Rhs)
|
|
{
|
|
return MakeStringView(Lhs).Equals(MakeStringView(Rhs), ESearchCase::IgnoreCase);
|
|
}
|
|
|
|
template <typename CharType>
|
|
inline bool operator<(const TSharedString<CharType>& Lhs, const TSharedString<CharType>& Rhs)
|
|
{
|
|
return MakeStringView(Lhs).Compare(MakeStringView(Rhs), ESearchCase::IgnoreCase) < 0;
|
|
}
|
|
|
|
UE_API bool LoadFromCompactBinary(FCbFieldView Field, FUtf8SharedString& OutString);
|
|
UE_API bool LoadFromCompactBinary(FCbFieldView Field, FWideSharedString& OutString);
|
|
|
|
} // UE::DerivedData
|
|
|
|
#undef UE_API
|