feat(string): add TStringView to standard C string conversion

This commit is contained in:
Redstone1024 2024-11-19 12:04:17 +08:00
parent 19a37ea072
commit edda2b83a1
2 changed files with 59 additions and 51 deletions

View File

@ -21,44 +21,6 @@ NAMESPACE_PRIVATE_BEGIN
template <typename T > struct TIsTString : FFalse { }; template <typename T > struct TIsTString : FFalse { };
template <typename T, typename A> struct TIsTString<TString<T, A>> : FTrue { }; template <typename T, typename A> struct TIsTString<TString<T, A>> : FTrue { };
template <typename T>
class TCStringFromTString final : FNoncopyable
{
public:
FORCEINLINE TCStringFromTString(const T* InPtr, bool bInDelete)
: Ptr(InPtr), bDelete(bInDelete)
{ }
FORCEINLINE TCStringFromTString(TCStringFromTString&& InValue)
: Ptr(InValue.Ptr), bDelete(Exchange(InValue.bDelete, false))
{ }
FORCEINLINE ~TCStringFromTString()
{
if (bDelete) delete[] Ptr;
}
FORCEINLINE TCStringFromTString& operator=(TCStringFromTString&& InValue)
{
if (bDelete) delete[] Ptr;
Ptr = InValue.Ptr;
bDelete = Exchange(InValue.bDelete, false);
return *this;
}
NODISCARD FORCEINLINE operator const T*() const { return Ptr; }
private:
const T* Ptr;
bool bDelete;
};
NAMESPACE_PRIVATE_END NAMESPACE_PRIVATE_END
template <typename T> concept CTString = NAMESPACE_PRIVATE::TIsTString<TRemoveCV<T>>::Value; template <typename T> concept CTString = NAMESPACE_PRIVATE::TIsTString<TRemoveCV<T>>::Value;
@ -1068,21 +1030,10 @@ public:
{ {
const_cast<ElementType*>(this->GetData())[this->Num()] = LITERAL(ElementType, '\0'); const_cast<ElementType*>(this->GetData())[this->Num()] = LITERAL(ElementType, '\0');
return NAMESPACE_PRIVATE::TCStringFromTString<ElementType>(this->GetData(), false); return *TStringView(this->GetData(), this->Num() + 1);
} }
if (this->Back() == LITERAL(ElementType, '\0')) return *TStringView(*this);
{
return NAMESPACE_PRIVATE::TCStringFromTString<ElementType>(this->GetData(), false);
}
ElementType* Buffer = new ElementType[this->Num() + 1];
Copy(Buffer);
Buffer[this->Num()] = LITERAL(ElementType, '\0');
return NAMESPACE_PRIVATE::TCStringFromTString<ElementType>(Buffer, true);
} }
/** @return The non-modifiable standard C character string version of the string. */ /** @return The non-modifiable standard C character string version of the string. */

View File

@ -31,6 +31,44 @@ NAMESPACE_PRIVATE_BEGIN
template <typename T> struct TIsTStringView : FFalse { }; template <typename T> struct TIsTStringView : FFalse { };
template <typename T> struct TIsTStringView<TStringView<T>> : FTrue { }; template <typename T> struct TIsTStringView<TStringView<T>> : FTrue { };
template <typename T>
class TCStringFromTStringView final : FNoncopyable
{
public:
FORCEINLINE TCStringFromTStringView(const T* InPtr, bool bInDelete)
: Ptr(InPtr), bDelete(bInDelete)
{ }
FORCEINLINE TCStringFromTStringView(TCStringFromTStringView&& InValue)
: Ptr(InValue.Ptr), bDelete(Exchange(InValue.bDelete, false))
{ }
FORCEINLINE ~TCStringFromTStringView()
{
if (bDelete) delete[] Ptr;
}
FORCEINLINE TCStringFromTStringView& operator=(TCStringFromTStringView&& InValue)
{
if (bDelete) delete[] Ptr;
Ptr = InValue.Ptr;
bDelete = Exchange(InValue.bDelete, false);
return *this;
}
NODISCARD FORCEINLINE operator const T*() const { return Ptr; }
private:
const T* Ptr;
bool bDelete;
};
NAMESPACE_PRIVATE_END NAMESPACE_PRIVATE_END
template <typename T> concept CTStringView = NAMESPACE_PRIVATE::TIsTStringView<TRemoveCV<T>>::Value; template <typename T> concept CTStringView = NAMESPACE_PRIVATE::TIsTStringView<TRemoveCV<T>>::Value;
@ -447,6 +485,25 @@ public:
return RFind([Char](ElementType C) { return C != Char; }, Index); return RFind([Char](ElementType C) { return C != Char; }, Index);
} }
public:
/** @return The non-modifiable standard C character string version of the string view. */
NODISCARD FORCEINLINE auto operator*() const
{
if (this->Back() == LITERAL(ElementType, '\0') || Contains(LITERAL(ElementType, '\0')))
{
return NAMESPACE_PRIVATE::TCStringFromTStringView<ElementType>(this->GetData(), false);
}
ElementType* Buffer = new ElementType[this->Num() + 1];
Copy(Buffer);
Buffer[this->Num()] = LITERAL(ElementType, '\0');
return NAMESPACE_PRIVATE::TCStringFromTStringView<ElementType>(Buffer, true);
}
public: public:
/** @return true if the string only contains valid characters, false otherwise. */ /** @return true if the string only contains valid characters, false otherwise. */