feat(string): add TStringView to standard C string conversion
This commit is contained in:
parent
19a37ea072
commit
edda2b83a1
@ -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. */
|
||||||
|
@ -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. */
|
||||||
|
Loading…
Reference in New Issue
Block a user