diff --git a/Redcraft.Utility/Source/Private/Testing/StringTesting.cpp b/Redcraft.Utility/Source/Private/Testing/StringTesting.cpp index fe516e8..010d96c 100644 --- a/Redcraft.Utility/Source/Private/Testing/StringTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/StringTesting.cpp @@ -33,208 +33,65 @@ void TestChar() always_check(CCharType); always_check(CCharType); } - + auto Test = [](TInPlaceType) { - always_check(FChar::IsAlnum(TEXT('0'))); - always_check(FChar::IsAlpha(TEXT('A'))); - always_check(FChar::IsLower(TEXT('a'))); - always_check(FChar::IsUpper(TEXT('A'))); - always_check(FChar::IsDigit(TEXT('0'))); - always_check(FChar::IsCntrl(TEXT('\n'))); - always_check(FChar::IsGraph(TEXT('!'))); - always_check(FChar::IsSpace(TEXT('\t'))); - always_check(FChar::IsBlank(TEXT(' '))); - always_check(FChar::IsPrint(TEXT('#'))); - always_check(FChar::IsPunct(TEXT('['))); - } + always_check(TChar::IsASCII(LITERAL(T, '0'))); + always_check(TChar::IsASCII(LITERAL(T, 'A'))); + always_check(TChar::IsASCII(LITERAL(T, 'a'))); + always_check(TChar::IsASCII(LITERAL(T, 'A'))); + always_check(TChar::IsASCII(LITERAL(T, '0'))); + always_check(TChar::IsASCII(LITERAL(T, '\n'))); + always_check(TChar::IsASCII(LITERAL(T, '!'))); + always_check(TChar::IsASCII(LITERAL(T, '\t'))); + always_check(TChar::IsASCII(LITERAL(T, ' '))); + always_check(TChar::IsASCII(LITERAL(T, '#'))); + always_check(TChar::IsASCII(LITERAL(T, '['))); - { - always_check(FWChar::IsAlnum(WTEXT('0'))); - always_check(FWChar::IsAlpha(WTEXT('A'))); - always_check(FWChar::IsLower(WTEXT('a'))); - always_check(FWChar::IsUpper(WTEXT('A'))); - always_check(FWChar::IsDigit(WTEXT('0'))); - always_check(FWChar::IsCntrl(WTEXT('\n'))); - always_check(FWChar::IsGraph(WTEXT('!'))); - always_check(FWChar::IsSpace(WTEXT('\t'))); - always_check(FWChar::IsBlank(WTEXT(' '))); - always_check(FWChar::IsPrint(WTEXT('#'))); - always_check(FWChar::IsPunct(WTEXT('['))); - } + always_check(TChar::IsAlnum(LITERAL(T, '0'))); + always_check(TChar::IsAlpha(LITERAL(T, 'A'))); + always_check(TChar::IsLower(LITERAL(T, 'a'))); + always_check(TChar::IsUpper(LITERAL(T, 'A'))); + always_check(TChar::IsDigit(LITERAL(T, '0'))); + always_check(TChar::IsCntrl(LITERAL(T, '\n'))); + always_check(TChar::IsGraph(LITERAL(T, '!'))); + always_check(TChar::IsSpace(LITERAL(T, '\t'))); + always_check(TChar::IsBlank(LITERAL(T, ' '))); + always_check(TChar::IsPrint(LITERAL(T, '#'))); + always_check(TChar::IsPunct(LITERAL(T, '['))); - { - always_check(FU8Char::IsAlnum(U8TEXT('0'))); - always_check(FU8Char::IsAlpha(U8TEXT('A'))); - always_check(FU8Char::IsLower(U8TEXT('a'))); - always_check(FU8Char::IsUpper(U8TEXT('A'))); - always_check(FU8Char::IsDigit(U8TEXT('0'))); - always_check(FU8Char::IsCntrl(U8TEXT('\n'))); - always_check(FU8Char::IsGraph(U8TEXT('!'))); - always_check(FU8Char::IsSpace(U8TEXT('\t'))); - always_check(FU8Char::IsBlank(U8TEXT(' '))); - always_check(FU8Char::IsPrint(U8TEXT('#'))); - always_check(FU8Char::IsPunct(U8TEXT('['))); - } + always_check(!TChar::IsAlnum(LITERAL(T, '$'))); + always_check(!TChar::IsAlpha(LITERAL(T, '0'))); + always_check(!TChar::IsLower(LITERAL(T, 'A'))); + always_check(!TChar::IsUpper(LITERAL(T, 'a'))); + always_check(!TChar::IsDigit(LITERAL(T, 'I'))); + always_check(!TChar::IsCntrl(LITERAL(T, '_'))); + always_check(!TChar::IsGraph(LITERAL(T, ' '))); + always_check(!TChar::IsSpace(LITERAL(T, '='))); + always_check(!TChar::IsBlank(LITERAL(T, '+'))); + always_check(!TChar::IsPrint(LITERAL(T, '\n'))); + always_check(!TChar::IsPunct(LITERAL(T, 'H'))); - { - always_check(FU16Char::IsAlnum(U16TEXT('0'))); - always_check(FU16Char::IsAlpha(U16TEXT('A'))); - always_check(FU16Char::IsLower(U16TEXT('a'))); - always_check(FU16Char::IsUpper(U16TEXT('A'))); - always_check(FU16Char::IsDigit(U16TEXT('0'))); - always_check(FU16Char::IsCntrl(U16TEXT('\n'))); - always_check(FU16Char::IsGraph(U16TEXT('!'))); - always_check(FU16Char::IsSpace(U16TEXT('\t'))); - always_check(FU16Char::IsBlank(U16TEXT(' '))); - always_check(FU16Char::IsPrint(U16TEXT('#'))); - always_check(FU16Char::IsPunct(U16TEXT('['))); - } + always_check( TChar::IsDigit(LITERAL(T, 'F'), 16)); + always_check(!TChar::IsDigit(LITERAL(T, 'G'), 16)); - { - always_check(FU32Char::IsAlnum(U32TEXT('0'))); - always_check(FU32Char::IsAlpha(U32TEXT('A'))); - always_check(FU32Char::IsLower(U32TEXT('a'))); - always_check(FU32Char::IsUpper(U32TEXT('A'))); - always_check(FU32Char::IsDigit(U32TEXT('0'))); - always_check(FU32Char::IsCntrl(U32TEXT('\n'))); - always_check(FU32Char::IsGraph(U32TEXT('!'))); - always_check(FU32Char::IsSpace(U32TEXT('\t'))); - always_check(FU32Char::IsBlank(U32TEXT(' '))); - always_check(FU32Char::IsPrint(U32TEXT('#'))); - always_check(FU32Char::IsPunct(U32TEXT('['))); - } + always_check(TChar::ToLower(LITERAL(T, 'i')) == LITERAL(T, 'i')); + always_check(TChar::ToUpper(LITERAL(T, 'l')) == LITERAL(T, 'L')); - { - always_check(!FChar::IsAlnum(TEXT('$'))); - always_check(!FChar::IsAlpha(TEXT('0'))); - always_check(!FChar::IsLower(TEXT('A'))); - always_check(!FChar::IsUpper(TEXT('a'))); - always_check(!FChar::IsDigit(TEXT('I'))); - always_check(!FChar::IsCntrl(TEXT('_'))); - always_check(!FChar::IsGraph(TEXT(' '))); - always_check(!FChar::IsSpace(TEXT('='))); - always_check(!FChar::IsBlank(TEXT('+'))); - always_check(!FChar::IsPrint(TEXT('\n'))); - always_check(!FChar::IsPunct(TEXT('H'))); - } + always_check(0x0 == TChar::ToDigit(LITERAL(T, '0'))); + always_check(0xF == TChar::ToDigit(LITERAL(T, 'f'))); + always_check(0xF == TChar::ToDigit(LITERAL(T, 'F'))); - { - always_check(!FWChar::IsAlnum(WTEXT('$'))); - always_check(!FWChar::IsAlpha(WTEXT('0'))); - always_check(!FWChar::IsLower(WTEXT('A'))); - always_check(!FWChar::IsUpper(WTEXT('a'))); - always_check(!FWChar::IsDigit(WTEXT('I'))); - always_check(!FWChar::IsCntrl(WTEXT('_'))); - always_check(!FWChar::IsGraph(WTEXT(' '))); - always_check(!FWChar::IsSpace(WTEXT('='))); - always_check(!FWChar::IsBlank(WTEXT('+'))); - always_check(!FWChar::IsPrint(WTEXT('\n'))); - always_check(!FWChar::IsPunct(WTEXT('H'))); - } + always_check(LITERAL(T, '0') == TChar::FromDigit(0x0)); + always_check(LITERAL(T, 'f') != TChar::FromDigit(0xF)); + always_check(LITERAL(T, 'F') == TChar::FromDigit(0xF)); + }; - { - always_check(!FU8Char::IsAlnum(U8TEXT('$'))); - always_check(!FU8Char::IsAlpha(U8TEXT('0'))); - always_check(!FU8Char::IsLower(U8TEXT('A'))); - always_check(!FU8Char::IsUpper(U8TEXT('a'))); - always_check(!FU8Char::IsDigit(U8TEXT('I'))); - always_check(!FU8Char::IsCntrl(U8TEXT('_'))); - always_check(!FU8Char::IsGraph(U8TEXT(' '))); - always_check(!FU8Char::IsSpace(U8TEXT('='))); - always_check(!FU8Char::IsBlank(U8TEXT('+'))); - always_check(!FU8Char::IsPrint(U8TEXT('\n'))); - always_check(!FU8Char::IsPunct(U8TEXT('H'))); - } - - { - always_check(!FU16Char::IsAlnum(U16TEXT('$'))); - always_check(!FU16Char::IsAlpha(U16TEXT('0'))); - always_check(!FU16Char::IsLower(U16TEXT('A'))); - always_check(!FU16Char::IsUpper(U16TEXT('a'))); - always_check(!FU16Char::IsDigit(U16TEXT('I'))); - always_check(!FU16Char::IsCntrl(U16TEXT('_'))); - always_check(!FU16Char::IsGraph(U16TEXT(' '))); - always_check(!FU16Char::IsSpace(U16TEXT('='))); - always_check(!FU16Char::IsBlank(U16TEXT('+'))); - always_check(!FU16Char::IsPrint(U16TEXT('\n'))); - always_check(!FU16Char::IsPunct(U16TEXT('H'))); - } - - { - always_check(!FU32Char::IsAlnum(U32TEXT('$'))); - always_check(!FU32Char::IsAlpha(U32TEXT('0'))); - always_check(!FU32Char::IsLower(U32TEXT('A'))); - always_check(!FU32Char::IsUpper(U32TEXT('a'))); - always_check(!FU32Char::IsDigit(U32TEXT('I'))); - always_check(!FU32Char::IsCntrl(U32TEXT('_'))); - always_check(!FU32Char::IsGraph(U32TEXT(' '))); - always_check(!FU32Char::IsSpace(U32TEXT('='))); - always_check(!FU32Char::IsBlank(U32TEXT('+'))); - always_check(!FU32Char::IsPrint(U32TEXT('\n'))); - always_check(!FU32Char::IsPunct(U32TEXT('H'))); - } - - { - always_check( FChar::IsDigit(TEXT('F'), 16)); - always_check(!FChar::IsDigit(TEXT('G'), 16)); - always_check( FWChar::IsDigit(WTEXT('F'), 16)); - always_check(!FWChar::IsDigit(WTEXT('G'), 16)); - always_check( FU8Char::IsDigit(U8TEXT('F'), 16)); - always_check(!FU8Char::IsDigit(U8TEXT('G'), 16)); - always_check( FU16Char::IsDigit(U16TEXT('F'), 16)); - always_check(!FU16Char::IsDigit(U16TEXT('G'), 16)); - always_check( FU32Char::IsDigit(U32TEXT('F'), 16)); - always_check(!FU32Char::IsDigit(U32TEXT('G'), 16)); - } - - { - always_check(FChar::ToLower(TEXT('i')) == TEXT('i')); - always_check(FChar::ToUpper(TEXT('l')) == TEXT('L')); - always_check(FWChar::ToUpper(WTEXT('l')) == WTEXT('L')); - always_check(FWChar::ToLower(WTEXT('i')) == WTEXT('i')); - always_check(FU8Char::ToLower(U8TEXT('i')) == U8TEXT('i')); - always_check(FU8Char::ToUpper(U8TEXT('l')) == U8TEXT('L')); - always_check(FU16Char::ToLower(U16TEXT('i')) == U16TEXT('i')); - always_check(FU16Char::ToUpper(U16TEXT('l')) == U16TEXT('L')); - always_check(FU32Char::ToLower(U32TEXT('i')) == U32TEXT('i')); - always_check(FU32Char::ToUpper(U32TEXT('l')) == U32TEXT('L')); - } - - { - always_check(0x0 == FChar::ToDigit(TEXT('0'))); - always_check(0xF == FChar::ToDigit(TEXT('f'))); - always_check(0xF == FChar::ToDigit(TEXT('F'))); - always_check(0x0 == FWChar::ToDigit(WTEXT('0'))); - always_check(0xF == FWChar::ToDigit(WTEXT('f'))); - always_check(0xF == FWChar::ToDigit(WTEXT('F'))); - always_check(0x0 == FU8Char::ToDigit(U8TEXT('0'))); - always_check(0xF == FU8Char::ToDigit(U8TEXT('f'))); - always_check(0xF == FU8Char::ToDigit(U8TEXT('F'))); - always_check(0x0 == FU16Char::ToDigit(U16TEXT('0'))); - always_check(0xF == FU16Char::ToDigit(U16TEXT('f'))); - always_check(0xF == FU16Char::ToDigit(U16TEXT('F'))); - always_check(0x0 == FU16Char::ToDigit(U16TEXT('0'))); - always_check(0xF == FU16Char::ToDigit(U16TEXT('f'))); - always_check(0xF == FU16Char::ToDigit(U16TEXT('F'))); - } - - { - always_check(TEXT('0') == FChar::FromDigit(0x0)); - always_check(TEXT('f') != FChar::FromDigit(0xF)); - always_check(TEXT('F') == FChar::FromDigit(0xF)); - always_check(WTEXT('0') == FWChar::FromDigit(0x0)); - always_check(WTEXT('f') != FWChar::FromDigit(0xF)); - always_check(WTEXT('F') == FWChar::FromDigit(0xF)); - always_check(U8TEXT('0') == FU8Char::FromDigit(0x0)); - always_check(U8TEXT('f') != FU8Char::FromDigit(0xF)); - always_check(U8TEXT('F') == FU8Char::FromDigit(0xF)); - always_check(U16TEXT('0') == FU16Char::FromDigit(0x0)); - always_check(U16TEXT('f') != FU16Char::FromDigit(0xF)); - always_check(U16TEXT('F') == FU16Char::FromDigit(0xF)); - always_check(U16TEXT('0') == FU16Char::FromDigit(0x0)); - always_check(U16TEXT('f') != FU16Char::FromDigit(0xF)); - always_check(U16TEXT('F') == FU16Char::FromDigit(0xF)); - } + Test(InPlaceType); + Test(InPlaceType); + Test(InPlaceType); + Test(InPlaceType); + Test(InPlaceType); + Test(InPlaceType); } void TestStringView() diff --git a/Redcraft.Utility/Source/Public/String/Char.h b/Redcraft.Utility/Source/Public/String/Char.h index 260a8c6..c03752a 100644 --- a/Redcraft.Utility/Source/Public/String/Char.h +++ b/Redcraft.Utility/Source/Public/String/Char.h @@ -156,6 +156,70 @@ struct TChar return false; } + NODISCARD FORCEINLINE static constexpr bool IsASCII(CharType InChar) + { + if constexpr (CSameAs) + { + constexpr bool ASCIICompatible = []() -> bool + { + constexpr char ASCIITable[] = + TEXT("\u0000\u0001\u0002\u0003\u0004\u0005\u0006") + TEXT("\a\b\t\n\v\f\r") + TEXT("\u000E\u000F") + TEXT("\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017") + TEXT("\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F") + TEXT(" !\"#$%&'()*+,-./0123456789:;<=>?") + TEXT("@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_") + TEXT("`abcdefghijklmnopqrstuvwxyz{|}~\u007F"); + + for (size_t Index = 0; Index <= 0x7F; ++Index) + { + if (ASCIITable[Index] != static_cast(Index)) return false; + } + + return true; + } + (); + + return ASCIICompatible && InChar <= 0x7F; + } + + else if constexpr (CSameAs) + { + constexpr bool ASCIICompatible = []() -> bool + { + constexpr wchar ASCIITable[] = + WTEXT("\u0000\u0001\u0002\u0003\u0004\u0005\u0006") + WTEXT("\a\b\t\n\v\f\r") + WTEXT("\u000E\u000F") + WTEXT("\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017") + WTEXT("\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F") + WTEXT(" !\"#$%&'()*+,-./0123456789:;<=>?") + WTEXT("@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_") + WTEXT("`abcdefghijklmnopqrstuvwxyz{|}~\u007F"); + + for (size_t Index = 0; Index <= 0x7F; ++Index) + { + if (ASCIITable[Index] != static_cast(Index)) return false; + } + + return true; + } + (); + + return ASCIICompatible && InChar <= 0x7F; + } + + else if constexpr (CSameAs || CSameAs || CSameAs || CSameAs) + { + return InChar <= 0x7F; + } + + else static_assert(sizeof(CharType) == -1, "Unsupported character type"); + + return false; + } + NODISCARD FORCEINLINE static constexpr bool IsAlnum(CharType InChar) { if constexpr (CSameAs || CSameAs)